Code Appendix
knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/',
echo=FALSE, warning=FALSE, message=FALSE, cache = TRUE)
# Read in relevant libraries
library(microbenchmark)
library(data.table)
library(quantmod)
library(ggplot2)
library(tseries)
library(zoo)
library(magrittr)
library(dplyr)
library(kableExtra)
library(formattable)
library(quantreg)
library(MTS)
library(plot3D)
library(citr)
library(formattable)
# Set up working directory
# setwd("~/Documents/GitHub/CaviaR")
# source('caviar_SM.R')
source('~/Documents/GitHub/CaviaR/caviar_SM.R')
# This code below is for use in the CAViaR sections.
# Here is code that I'll wrap some parts in to avoid superfluous output
quiet <- function(x) {
sink(tempfile())
on.exit(sink())
invisible(force(x))
}
#' This is a function which pulls data for use in the CAViaR model
#'
#' @param symbol - symbol to pull
#' @param compl_case - defaults to true...only includes complete cases in the data
#' @param adj_close - use adjusted closing prices. Default is yes.
#' @param log_return - use log return? Default is yes.
#'
#' @return - a data frame which can be fed into later functions
#' @export
#'
#' @examples - data_pull("SPY")
data_pull = function(symbol, compl_case = 1, adj_close = 1, log_return = 1, start_date = "1900-01-01", end_date = Sys.Date()){
# Pull in data from quantmod
response_pull = getSymbols(symbol, auto.assign = FALSE, from = start_date, to = end_date)
# Get adjusted closing price
if (adj_close == TRUE){
df = Ad(response_pull)
} else {
df = Cl(response_pull)
}
# Return complete cases only
if (compl_case == TRUE){
df = df[complete.cases(df), ]
} else{
df = df
}
# Calculate log return of data
if (log_return == TRUE){
lr = log(df[,1]/shift(df[,1], 1, type = "lag"))
# Combine data
df_out = cbind(df, lr)
# Rename the data
colnames(df_out) <- c(sym=symbol, paste0(symbol, "_log_return"))
} else{
df_out = df
}
# Return data
return(df_out)
}
#' Pull the data and run the CAViaR function on it
#'
#' @param input_data - data to use in the function
#' @param range_data - range of the data to use
#'
#' @return - a list of values from the caviar function
#' @export
#'
#' @examples - caviar_pull(spy)
caviar_pull = function(input_data, range_data = (2:dim(input_data)[1])){
# Run the caviar data
caviar <- caviarOptim(input_data[range_data,2])
return(caviar)
}
#' Function for producing rolling predictions
#' Model 1 = Symmetric Absolute Value, 2 = Asymmetric slope, 3 = Indirect GARCH, 4 = Adaptive
#'
#' @param input_data - input data from the previous function
#' @param range_data - range of the data to consider
#' @param nfcst - number of forecasts to make
#' @param model - model to use (integers 1 through 4). Defaults to 1.
#' @param level - level of significance to use.
#' @param G - argument for the k parameter in the 4th model (adaptive). Default is 5
#'
#' @return - an xts object which contains rolling CAViaR predictions
#' @export
#'
#' @examples - rolling_predictions(spy, nfcst = 22)
rolling_predictions = function(input_data, range_data = (2:dim(input_data)[1]), nfcst = 250, model =1, level = 0.01, G = 5, col = 2){
# Run the varpredict function
varpredict <- rollapplyr(input_data[range_data,col], length(range_data) - nfcst, caviarOptim, model, level, predict = 1, k = G) %>% lag
# Eliminate NAs
# pred_no_na = na.omit(varpredict)
# Return the data
# return(pred_no_na)
return(varpredict)
}
#' Function to Calculate Loss from the above predictions
#'
#' @param symbol - symbol to work with from quantmod. Must be in quotations to work
#' @param start_dt - start date of the data to build the forecast on
#' @param end_dt - end date of the data to build the forecast on
#' @param nfcst - number of data points to use in the forecast
#' @param model - model to use. Defaults to 1
#' @param level - level of significance. Defaults to 1%
#' @param G - argument for the k parameter in the 4th model (adaptive). Default is 5
#'
#' @return - loss using absolute value
#' @export - a plot of the data
#'
#' @examples
loss_calc_uv = function(symbol, start_dt, end_dt, nfcst, model = 1, level = 0.01, G = 5){
# Pull in the data
raw_data = data_pull(symbol, start_date = start_dt, end_date = end_dt)
# Forecast based on the data
fcst = na.omit(rolling_predictions(raw_data, nfcst = nfcst, model = model, level = level, G = G))*(-1)
# Extract actuals
act = tail(raw_data, n = nfcst)[,2]
# Join the two together and rename
join = merge(fcst,act,all=TRUE)
colnames(join) <- c("Fcst_VaR", "Act_Return")
# print(join)
# Calculate the losses
loss = abs(sum(ifelse(act > fcst, level, (-1)*(1-level))))
# Plot the data
plot = plot.xts(join, col = c("red", "black"), lty = c(2,1), main = "Log Return from the SPY vs. Fcst. VaR",grid.col = NA, legend.loc = "bottomleft")
return(list(loss, plot, act, fcst))
}
#' This is a function which creates a data frame for the response and explanatory variables that we'll feed into the diffusion index
#'
#' @param symbol_list - a list of symbols recognizable by the
#' @param resp_var - the response variable we'd like to forecast; default is SPY
#' @param compl_case - defaults to true...only includes complete cases in the data
#' @param adj_close - use adjusted closing prices for the explanatory variables? default is 1 for YES
#' @param resp_adj_close - use adjusted closing prices for the explanatory variables? default is 1 for YES
#' @param start_date - starting data to use
#' @param end_date - ending date of the data
#' @param lag_pred - do we lag the predictions? It is STRONGLY recommended that this is 0
#'
#' @return - a data frame which can be fed into the SWfore function
#' @export
#'
#' @examples - diff_index_df(c("XLF", "XLE", "PSCT", "XLV", "VPU", "XLP", "IGF", "XWEB", "PPTY"))
diff_index_df = function(symbol_list, resp_var = "SPY", compl_case = 1, adj_close = 1, resp_adj_close = 1, start_date = "1900-01-01", end_date = Sys.Date(), lag_pred = 1){
# Pull in response variable
response_pull = getSymbols(resp_var, auto.assign = FALSE, from = start_date, to = end_date)
# Get adjusted closing price
if (resp_adj_close == TRUE){
diff_df = Ad(response_pull)
} else {
diff_df = Cl(response_pull)
}
# Loop through the symbols and join in data
for (i in 1:length(symbol_list)){
# Pull closing price
expl_pull = getSymbols(symbol_list[i], auto.assign = FALSE, from = start_date, to = end_date)
# Extract closing price - 4th element
if (adj_close == TRUE){
expl_cl = Ad(expl_pull)
} else {
expl_cl = Cl(expl_pull)
}
# New code for 4.16.2020 - lag the explanatory variables
if (lag_pred == TRUE){
# Lag the explanatory variables by 1
lag_exp = lag(expl_cl, 1)
# Append the first lag to the data frame
diff_df = merge(diff_df, lag_exp, join = "left", fill = NA)
} else{
# Return the data frame without lags
diff_df = merge(diff_df, expl_cl, join = "left", fill = NA)
}
}
if (lag_pred == TRUE){
# Chop off the first row
diff_df = diff_df[-1,]
}
else {
print("PLEASE NOTE - the explanatory variables in this DF are NOT lagged. Be careful to avoid look-ahead bias!")
}
# Return complete cases only
if (compl_case == TRUE){
diff_df_out = diff_df[complete.cases(diff_df), ]
} else{
diff_df_out = diff_df
}
return(diff_df_out)
}
#' Converts a diff_df into a data frame with approximate percentage changes diff(log(diff_df))
#'
#' @param diff_df - output of the diff_index_df function with complete cases
#'
#' @return - retuns the differenced data
#' @export
#'
#' @examples - pc_diff_index(test_compl)
pc_diff_index = function(diff_df){
# Difference the log of the data
pc_diff_index = diff(log(diff_df))
# Remove the first row
pc_diff_index_out = pc_diff_index[-1,]
return(pc_diff_index_out)
}
#' Below is the modified diffusion index code.
#'
#' @param y - response variable
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param m - number of diffusion indexes used
#' @param tau - VaR level to use; must be between 0 and 1
#' @param end - specifies an alternate ending value
#' @param print_mdl - print the model summary and the MSE
#'
#' @return - returns a list of variables for use in the diffusion index
#' @export
#'
#' @examples
mod_di = function (y, x, orig, m, tau, end = NULL, print_mdl = 0)
{
# Converts the response variables into a matrix
if (!is.matrix(x))
x = as.matrix(x)
# nT is number of t time-steps
nT = dim(x)[1]
# Add a line to establish the number of data points used in the test.
if (is.null(end) != TRUE){
nT = end
}
# k is the number of diffusion indices used
k = dim(x)[2]
# Sanity checks to ensure that the origin isn't past the number of time points
if (orig > nT)
orig = nT
# Makes sure that there aren't more predictors than there variables in the dataset
if (m > k)
m = k
# Makes sure there are at least some variables
if (m < 1)
m = 1
# Subdivides the dataframe
x1 = x[1:orig, ]
# Calculates means of each row
me = apply(x1, 2, mean)
# Calculates standard deviations of each column
se = sqrt(apply(x1, 2, var))
# Creates a matrix x1, which normalizes all the columns.
# This may be an issue since it assumes that the distribution is sufficiently described by the first two moments
x1 = x
for (i in 1:k) {
x1[, i] = (x1[, i] - me[i])/se[i]
}
V1 = cov(x1[1:orig, ])
# Performs an eigen decomposition
m1 = eigen(V1)
# Selects eigenvalues
sdev = m1$values
# Selects eigenvectors
M = m1$vectors
# Makes a smaller matrix
M1 = M[, 1:m]
# This is the diffusion index model - [orig x p]*[p x m] = [orig x m]
Dindex = x1 %*% M1
# Cut down both the response and predictors to be a reasonable size
y1 = y[1:orig]
DF = Dindex[1:orig, ]
# Apply the linear model - HERE is the key.
# mm = lm(y1 ~ DF) - old function
mm = rq(y1 ~ DF, tau = tau)
# Print the data
if (print_mdl == 1){
print(summary(mm))
}
# Puts coefficients in a matrix
coef = matrix(mm$coefficients, (m + 1), 1)
# Initializes yhat variables and MSE
yhat = NULL
MSE = NULL
if (orig < nT) {
# Creates a nfcst by (m+1) matrix
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT,
])
# [nfcstx(m+1)]*[(m+1)x1] = [nfcstx1]
yhat = newx %*% coef
# Calculates errors
err = y[(orig + 1):nT] - yhat
MSE = mean(err^2)
if (print_mdl == 1){
cat("MSE of out-of-sample forecasts: ", MSE, "\n")
}
}
SWfore <- list(coef = coef, yhat = yhat, MSE = MSE, loadings = M1,
DFindex = Dindex)
}
#' Below is the modified diffusion index code to include lagged variables.
#'
#' @param y - response variable
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param m - number of diffusion indexes used
#' @param tau - VaR level to use; must be between 0 and 1
#' @param ar_tf - AR transformation type. (1 - no transformation,
#' 2 - absolute value, 3 - asymmetric slope)
#' @param p - number of AR lags to include. Default is one.
#' @param print_mdl - option to print the model summary to make sure everytning is ok. 0 is default.
#' @param model - model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
#'
#' @return - returns a list of variables for use in the diffusion index
#' @export
#'
#' @examples
mod_di_wl = function (y, x, orig, m, tau, ar_tf = 1, p = 1, print_mdl = 0, model = 1, end = NULL)
{
# Converts the response variables into a matrix
if (!is.matrix(x))
x = as.matrix(x)
# nT is number of t time-steps
nT = dim(x)[1]
# Add a line to establish the number of data points used in the test.
if (is.null(end) != TRUE){
nT = end
}
# k is the number of diffusion indices used
k = dim(x)[2]
# Sanity checks to ensure that the origin isn't past the number of time points
if (orig > nT)
orig = nT
# Makes sure that there aren't more predictors than there variables in the dataset
if (m > k)
m = k
# Makes sure there are at least some variables
if (m < 1)
m = 1
# Subdivides the dataframe
x1 = x[1:orig, ]
# Calculates means of each row
me = apply(x1, 2, mean)
# Calculates standard deviations of each column
se = sqrt(apply(x1, 2, var))
# Creates a matrix x1, which normalizes all the columns.
# This may be an issue since it assumes that the distribution is sufficiently described by the first two moments
x1 = x
for (i in 1:k) {
x1[, i] = (x1[, i] - me[i])/se[i]
}
V1 = cov(x1[1:orig, ])
# Performs an eigen decomposition
m1 = eigen(V1)
# Selects eigenvalues
sdev = m1$values
# Selects eigenvectors
M = m1$vectors
# Makes a smaller matrix
M1 = M[, 1:m]
# This is the diffusion index model - [orig x p]*[p x m] = [orig x m]
Dindex = x1 %*% M1
# Cut down both the response and predictors to be a reasonable size
y1 = y[1:orig]
DF = Dindex[1:orig, ]
# Copy the data frame
DF_wl = Dindex
# Lag the y-variable
for (i in 1:p){
# Create a lagged variable
lag_var = lag(y, i)
# Append the first lag to the data frame
DF_wl = cbind(DF_wl,lag_var)
}
# Identify the right columns
l_ar = ncol(DF_wl)
f_ar = l_ar - p + 1
# Keep the last columns kept to the side
all_lag = DF_wl[,(f_ar:l_ar)]
# Cut off the first row to avoid NA's
DF_trim = DF_wl[1:orig,]
# Rename the columns
# Here's the new function with an untransformed AR(p) lag
if (ar_tf == 1){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),])
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Assign the names
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
}
# Here's the new function with an SAV AR(p) lag
if (ar_tf == 2){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),-(f_ar:l_ar)], abs(DF_trim[-(1:p),(f_ar:l_ar)]))
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Assign the names. Note that this is a matrix
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
}
# Here's the new function with an asymmetric slope for the AR(1) lag
# Indicator; 0 if percent change is negative, 1 if it's positive
# indi = ifelse(DF_trim[,ar] < 0, 0, 1)
if (ar_tf == 3){
# Create a matrix of indicators
indi_mat = matrix(0, nrow(DF_wl), p)
# Generalize the above code
for (i in 1:p){
# Populate the indicator
indi_mat[,i] = ifelse(DF_wl[,f_ar + i - 1] < 0, 0, 1)
}
}
# Fitting the regression
if (ar_tf == 3){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),-(f_ar:l_ar)], DF_trim[-(1:p),(f_ar:l_ar)], indi_mat[((p+1):orig),])
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+2*p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Last are the positive indicator variables
for (i in 1:p){
nvec[i+1+m+p] = paste0("Pos_Val_for_Lag_", i)
}
# Assign the names. Note that this is a matrix
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
# mm = rq(y1[-(1:p)] ~ DF_trim[-(1:p),-(f_ar:l_ar)] + DF_trim[-(1:p),(f_ar:l_ar)] + indi_mat[((p+1):orig),], tau = tau)
# Add a different line to account for the indicator variable
# intercept + m + 2*nlag to account for the number of indicator variables
coef = matrix(mm$coefficients, (1 + m + 2*p), 1)
}
if (print_mdl == 1){
print(summary(mm))
}
# Puts coefficients in a matrix - added the AR terms
# coef = matrix(mm$coefficients, (m + 1), 1)
if (ar_tf != 3){
coef = matrix(mm$coefficients, (1 + m + p), 1)
}
# Initializes yhat variables and MSE
yhat = NULL
loss = NULL
if (orig < nT) {
# Creates a nfcst by (m+2) matrix
# Add on the lagged variables
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT, ], all_lag[(orig+1):nT,])
# Incorporate lagged variables
if (ar_tf == 3){
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT, ], all_lag[(orig+1):nT,], indi_mat[(orig+1):nT,])
}
# [nfcstx(m+1)]*[(m+1)x1] = [nfcstx1]
yhat = newx %*% coef
# Calculates errors
loss = abs(sum(ifelse(y[(orig + 1):nT] > yhat, tau, (-1)*(1-tau))))
# Modifying this part to only print this if specified
if (print_mdl == 1){
cat("Losses of out-of-sample forecasts: ", loss, "\n")
}
}
SWfore <- list(coef = coef, yhat = yhat, loss = loss, loadings = M1,
DFindex = Dindex, name_vector = nvec)
}
# Decide on the optimal number of vectors.
# (y, x, orig, m, tau)
#' Function that calculates loss over a given period of time for the diffusion index model
#'
#' @param y - response variables
#' @param x - explanatory variable
#' @param orig - forecast origin
#' @param end - forecasting ending. Note: as the function is currently written on 2/24, this option doesn't do anything.
#' @param m - number of diffusion indices to use
#' @param tau - VaR level
#' @param mod_di - use the modified DI?
#'
#' @return - returns a list of the loss sum and the loss vector
#' @export
#'
#' @examples - loss_calc(pc_df[,1], pc_df[,-1], 757, 1027, 1, 0.01)
loss_calc = function(y, x, orig, m, tau, mod_di = 0, ar_tf = 1, p = 1, print_mdl = 0, model = 1, end = NULL){
# Extract y_hat values
if (mod_di == 0){
di = mod_di(y=y,x=x,orig=orig,m=m, tau=tau, end = end, print_mdl = print_mdl)
}
else {
di = mod_di_wl(y=y,x=x,orig=orig,m=m, tau=tau, ar_tf = ar_tf, p = p, print_mdl = print_mdl, model = model, end = end)
}
# mod_di_wl = function (y, x, orig, m, tau, ar_tf = 1, p = 1, print_mdl = 0, model = 1)
yhat = di$yhat[1:(end-orig)]
# Calculate the loss
# Initialize loss vector
lvec = rep(0,(end-orig))
# Take the difference
for (i in 1:(end-orig)){
# Calculate an indicator variable
ind = ifelse(y[orig+i] < yhat[i], 1,0)
# Use indicator in function below
lvec[i] = (tau - ind)*(y[orig+i] - yhat[i])
}
# Add up the losses - change to look at sum of losses. Won't change decision criterion
sumloss = sum(lvec)
# sumloss = sum(lvec)/length(lvec)
return(list(sumloss,lvec))
}
#' Function that selects the optimal number of predictors
#'
#' @param y - response vector
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param end - ending of validation set
#' @param tau - VaR in question
#' @param low_m - low value of m to consider
#' @param high_m - high value of m to consider
#'
#' @return - returns the optimal value of m
#' @export
#'
#' @examples - opt_m(pc_df[,1], pc_df[,-1], 757, 1027, 0.01, low_m =1, high_m = 5)
opt_m = function(y, x, orig, end = NULL, tau, low_m = 1, high_m, mod_di = 0, ar_tf = 1, p = 1, print_mdl = 0, model = 1, rowname = NULL){
# Initialize a loss vector
loss_vec = rep(0,high_m-low_m + 1)
# Initialize an m vector
m_vec = seq(low_m, high_m, by = 1)
# Loop through and populate the loss vector
for (i in 1:length(loss_vec)){
loss_vec[i] = quiet(loss_calc(y=y,x=x,orig=orig,end=end, m = m_vec[i], tau = tau, mod_di = mod_di, ar_tf = ar_tf, p = p, print_mdl = print_mdl, model = model))[[1]]
}
# Find the minimizer
opt_m = which.min(loss_vec)
opt_p = NA
# Combine into a data frame
df = as.data.frame(cbind(opt_m, opt_p))
names(df) <- c("Optimal m", "Optimal p")
# Assign a rowname
if (is.null(rowname) == TRUE){
# Write the row names
rownames(df) <- c("MV CAViaR")
}
else {
rownames(df) <- rowname
}
# Return the loss_vector and the minimzer
return(list(opt_m, loss_vec, df))
}
#' Function that selects the optimal number of lags
#'
#' @param y - response vector
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param end - ending of validation set
#' @param tau - VaR in question
#' @param low_m - low value of m to consider
#' @param high_m - high value of m to consider
#'
#' @return - returns the optimal value of m
#' @export
#'
#' @examples - opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = 757, end = 1007, tau = 0.01, low_m =1, high_m = 5, low_p = 1, high_p = 10, ar_tf = 2, mod_di = 1)
opt_mp = function(y, x, orig, end = NULL, tau, low_m = 1, high_m, low_p = 1, high_p, mod_di = 0, ar_tf = 1, print_mdl = 0, model = 1, print_mp = 0, rowname = NULL){
# Initialize a loss matrix
loss_mat = matrix(0, high_p-low_p + 1,high_m-low_m + 1)
# Initialize a p vector
p_vec = seq(low_p, high_p, by = 1)
# Loop through and populate the loss vector
for (i in 1:nrow(loss_mat)){
loss_mat[i,] = opt_m(y = y, x = x, orig = orig, end = end, tau = tau, low_m = low_m, high_m = high_m, p = i, mod_di = mod_di, ar_tf = ar_tf, print_mdl = print_mdl, model = model)[[2]]
}
# Find the minimizer
opt_p = which(loss_mat == min(loss_mat), arr.ind = TRUE)[1,1]
opt_m = which(loss_mat == min(loss_mat), arr.ind = TRUE)[1,2]
# Print the optimal p and optimal m
df = as.data.frame(cbind(opt_m, opt_p))
names(df) <- c("Optimal m", "Optimal p")
# Assign a rowname
if (is.null(rowname) == TRUE){
if (ar_tf == 1){
# Write the row names
rownames(df) <- c("MV CAViaR + AR")
} else if (ar_tf == 2){
# Write the row names
rownames(df) <- c("MV CAViaR + SAV")
} else if (ar_tf == 3){
# Write the row names
rownames(df) <- c("MV CAViaR + AS")
} else {
rownames(df) <- c("Unknown Model")
}
}
else {
rownames(df) <- rowname
}
# Print the df if the option is turned on
if (print_mp == 1){
print(df)
}
# Return the loss_vector and the minimzer
return(list(opt_m, opt_p, loss_mat, df))
}
#' A function that combines optimal values of m and p into a final table
#'
#' @param m1 - the data frame from the "MV CAViaR" run
#' @param m2 - the data frame from the "MV CAViaR + AR" run
#' @param m3 - the data frame from the "MV CAViaR + SAV" run
#' @param m4 - the data frame from the "MV CAViaR + AS" run
#'
#' @return - a nicely formatted table
#' @export
#'
#' @examples - pretty_pm(opt_pred_nl[[3]], opt_pm_m1[[4]], opt_pm_m2[[4]], opt_pm_m3[[4]])
pretty_pm = function(m1, m2, m3, m4){
# Merge the individual data frames
pm_pretty_df = rbind(m1, m2, m3, m4)
# Format nicely
pm_pretty_df %>% kable(caption = "Optimal Number of Diffusion Indices (m) and Lags (p) for Different Models", digits = 0) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = "The MV CAViaR model doesn't have an optimal value for p because there are no AR lags in the model"
)
}
#' Here is a function that runs the univariate CAViaR model 4 times
#'
#' @param df - the percent change data frame to consider
#' @param nfcst - number of forecasts to run
#' @param tau - the VaR level to consider
#' @param no_run - specifies if any models should not be run
#'
#' @return - a list of the 4 univariate model forecasts
#' @export
#'
#' @examples - aceg = gen_uv_test(pc_df, 1, 0.05, no_run = c(1,1,0,1))
gen_uv_test = function(df, nfcst, tau, no_run = c(0,0,0,0)){
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# Initialize a list
out_list = list()
# Run the four models - model 1; SAV
if (no_run[1] == 0){
uvcav_1 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 1, G = 10, col = 1, level = tau)
}
# Add a filler if there's no entry
else {
uvcav_1 = 0
}
# Model 2 - AS
if (no_run[2] == 0){
uvcav_2 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 2, G = 10, col = 1, level = tau)
}
else {
uvcav_2 = 0
}
# Model 3 - GARCH
if (no_run[3] == 0){
uvcav_3 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 3, G = 10, col = 1, level = tau)
}
else {
uvcav_3 = 0
}
# Model 4 - Adaptive
if (no_run[4] == 0){
uvcav_4 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 4, G = 10, col = 1, level = tau)
}
else {
uvcav_4 = 0
}
# Export the data as a list
return(list(uvcav_1, uvcav_2, uvcav_3, uvcav_4))
}
#' Function to plot the data which we generate in previous functions
#'
#' @param plot_matrix - matrix with the data to plot
#' @param norm_value - what to subtact from the data to make it on a percentage change basis. Default is 100.
#'
#' @return
#' @export - a plot of the data by diffusion index number
#'
#' @examples = plt_data(plot_mtx[[1]]), abc = plt_data(plot_mat, tau = 0.01)
plt_data = function(plot_matrix, tau, resp_var, ntest){
# Establish a maximum and minimum value
max_val = max(plot_matrix[,1:ncol(plot_matrix)])
min_val = min(plot_matrix[,1:ncol(plot_matrix)])
# Calculate inital and ending time value
start = index(plot_matrix)[1]
end = index(plot_matrix)[nrow(plot_matrix)]
ind_vals = index(plot_matrix) - start
# Create an initial plot and add lines
for (i in 1:ncol(plot_matrix)){
if (i == 1){
# 4/2/2020 - fixing the index
plot.ts(ind_vals,plot_matrix[,i], type = "l", xlab = paste("Days Since", as.Date(start)), ylab = "Percent Change in PG", ylim = c(min_val,max_val), lwd = 1, main = paste("Predicting", resp_var, "Returns from", as.Date(start), "to", as.Date(end)), sub = paste("The VaR Level is ", 100*tau, "%", "; There are ", ntest, " Trading Days Plotted Above", sep = ""))
# plot.ts(index(plot_matrix), plot_matrix[,i], type = "l", xlab = "Trading Days", ylab = "Percent Change in PG", ylim = c(min_val,max_val), lwd = 1, main = "Predicting PG Returns Over Last 250 Trading Days in 2008", sub = paste("The VaR Level is ", 100*tau, "%", sep = ""))
} else if(i %in% seq(2,8,1)) {
lines(ind_vals,plot_matrix[,i], col = i-1, lty = 2)
} else {
lines(ind_vals,plot_matrix[,i], col = i-1, lty = 2, lwd = 2)
}
}
# Define a sequence for plotting
plot_seq = seq(1, ncol(plot_matrix))
legend("topleft", legend = c(colnames(plot_matrix)), col = plot_seq, lty = c(1, rep(2, 7), rep(3, ifelse(ncol(plot_matrix)-8 <= 0, 0, ncol(plot_matrix)-8))), lwd = c(1, rep(1, 7), rep(2, ifelse(ncol(plot_matrix)-8 <= 0, 0, ncol(plot_matrix)-8))))
# Add a line for 0
# abline(h = 0, col = "black", lty = 2)
}
#' A function to calculate losses based on the test sample
#'
#' @param true_vec - the true vector of returns
#' @param pred_vec - the predicted vector from the model runs
#' @param tau - VaR level. Must match what the model used
#'
#' @return - total losses and the entire loss vector
#' @export
#'
#' @examples
loss_test = function(true_vec, pred_vec, tau){
# Initialize a loss vector
lvec = rep(0, length(true_vec))
# Initialize a break vector to see when VaR is broken
bvec = rep(0, length(true_vec))
for (i in 1:length(true_vec)){
# Calculate an indicator variable
bvec[i] = ifelse(true_vec[i] < pred_vec[i], 1,0)
# Use indicator in function below
lvec[i] = (tau - bvec[i])*(true_vec[i] - pred_vec[i])
}
# Add up the losses
# sumloss = sum(lvec)/length(lvec)
sumloss = sum(lvec)
# Add up the VaR breakage
varbreak = sum(bvec)/length(bvec)
return(list(sumloss,lvec, varbreak, bvec))
}
#' A function to calculate losses based on the plot matrix
#'
#' @param data_mat - a matrix of forecasted VaR values, with the true value in the first column
#' @param tau - VaR level. Must match what the model used
#'
#' @return - a list of four items.
#' 1 = a vector of the losses of all models.
#' 2 = a vector showing the percentage of VaR breaks by model
#' 3 = the loss matrix
#' 4 = the break matrix
#' @export
#'
#' @examples
gen_loss_test = function(data_mat, tau){
# Initialize loss and break matrices
lmat = bmat = matrix(0, nrow = nrow(data_mat), ncol = ncol(data_mat)-1)
# bvec = rep(0, length(true_vec))
# Populate the matrices
for (i in 1:nrow(lmat)){
for (j in 1:(ncol(lmat))){
# Calculate an indicator variable
bmat[i,j] = ifelse(data_mat[i,1] < data_mat[i,j+1], 1,0)
# Use indicator in function below
lmat[i,j] = (tau - bmat[i,j])*(data_mat[i,1] - data_mat[i,j+1])
}
}
# Add up the losses
sumloss = colSums(lmat)
# Add up the VaR breakage
varbreak = colSums(bmat)/nrow(bmat)
return(list(sumloss, varbreak, lmat, bmat))
}
#' A function to make a nice comparison of losses
#'
#' @param data_mat - input data matrix used in the calculation of losses
#' @param loss_list - a list of the losses calculated from the CAViaR function
#' @param tau - the risk level used
#' @param ntest - the number of test points
#'
#' @return
#' @export - returns a nicely formatted table
#'
#' @examples - pretty_tables(plot_mat, l_list, tau = 0.01)
pretty_tables = function(data_mat, loss_list, tau, ntest){
# Combine into a data frame
df = as.data.frame(rbind(loss_list[[1]], loss_list[[2]]))
# Calculate inital and ending time value
start = index(data_mat)[1]
end = index(data_mat)[nrow(data_mat)]
# Add row/column names
colnames(df) <- colnames(data_mat[,-1])
rownames(df) <- c("Losses", "VaR Breaks (%)")
# Convert to a table
df %>% kable(caption = paste("Comparison of VaR Methods for a ", tau*100, "% VaR", sep = ""), digits = 3) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = paste("Calculated using", ntest, "trading days from", as.Date(start), "to", as.Date(end)))
}
#' A dressed up version of the export function
#'
#' @param var_file - file to export
#' @param path - filepath
#' @param filename - name of the file, ending with .CSV
#'
#' @return
#' @export - exported CSV file
#'
#' @examples - exp_func(var_file = var_1pc_2016_usetf[[1]], path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "TEST.csv")
exp_func = function(var_file, path, filename){
# Write a zoo
write.zoo(var_file, paste0(path, filename), quote = FALSE, sep = ",")
}
# exp_func(var_file = var_1pc_2016_usetf[[1]], path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "TEST.csv")
#' This is the "master" function where we'll evaluate the importance of the VaR model over several time periods
#'
#' @param symbol_list - a list of symbols to feed into the model
#' @param resp_var - the response variable
#' @param compl_case - should the model require complete cases? Default value is 1.
#' @param adj_close - use adjusted close price for the predictors? Default value is 1.
#' @param resp_adj_close - use adjusted close price for the response? Default value is 1.
#' @param start_date - start date to pull data from
#' @param end_date - end date to pull data from
#' @param nval - number of validation points to use
#' @param ntest - number of test points to use
#' @param tau - VaR level to use
#' @param low_m - low number of predictors to test
#' @param high_m - low number of predictors to test
#' @param uv_list - a list of a pre-run univariate model. If a data frame is not provided, the lengthy uv model will run
#' @param no_run - things not to run in the model
#' @param low_p - low value for number of lags
#' @param high_p - high value for number of lags
#' @param na_interp - should the function interpolate NA's
#' @param print_mdl - print the model summaries?
#' @param print_mp - print the optimal values for p and m
#' @param lag_pred - do you want to lag the m predictors (default is 1; strongly recommended)
#' @param rowname - what to name the rows of the nice p and m matrix
#' @param export_csv - do you want to export a CSV? Default is 1.
#' @param path - path to export the CSV
#' @param filename - what to name the CSV
#'
#' @return - a list of the plot matrix, a plot, a list with losses, and a table
#' @export - a plot and a table
#'
#' @examples - cav_simul(c("DIS", "GE", "IBM", "MMM", "XOM"), resp_var = "PG", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 5, tau = 0.01, uv_list = uv_cav_list)
cav_simul = function(symbol_list, resp_var, compl_case = 1, adj_close = 1, resp_adj_close = 1, start_date = "1900-01-01", end_date = Sys.Date(), nval, ntest, tau, low_m = 1, high_m, low_p = 1, high_p, uv_list = NULL, no_run = c(0,0,0,0), na_interp = TRUE, print_mdl = 0, print_mp = 0, lag_pred = 1, rowname = NULL, export_csv = 1, path, filename){
# Select data parameters, pull the data, and percent change the data
df = diff_index_df(symbol_list = symbol_list, resp_var = resp_var, compl_case = compl_case, adj_close = adj_close, resp_adj_close = resp_adj_close, start_date = start_date, end_date = end_date, lag_pred = lag_pred)
# Take the percent change of the data
pc_df = pc_diff_index(df)
# Extract the legnth of the data frame
nr = test_end = nrow(pc_df)
# Calculate the start of the val period, the end of the val period, and the beginning and end of test period
test_orig = test_end - ntest
val_end = test_orig
val_orig = test_orig - nval
# Test for the optimal number of parameters
opt_pred_nl = opt_m(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, rowname = rowname)
opt_pred_art1 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p,mod_di = 1, ar_tf = 1, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
opt_pred_art2 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p,mod_di = 1, ar_tf = 2, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
opt_pred_art3 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p, mod_di = 1, ar_tf = 3, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
# gen_uv_test(pc_df, 1, 0.05, no_run = c(1,1,0,1))
# Use the above forecasts to input into the above
mv_fcst = mod_di(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_nl[[1]], tau = tau, print_mdl = print_mdl)
mv_fcst_art1 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art1[[1]], p = opt_pred_art1[[2]], tau = tau, ar_tf = 1, print_mdl = print_mdl)
mv_fcst_art2 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art2[[1]], p = opt_pred_art2[[2]], tau = tau, ar_tf = 2, print_mdl = print_mdl)
mv_fcst_art3 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art3[[1]], p = opt_pred_art3[[2]], tau = tau, ar_tf = 3, print_mdl = print_mdl)
# Calculate the number of predictions
if (is.null(uv_list) == TRUE){
# Print a warning
print("WARNING: Not supplying an input data frame will require this function to run for a significant amount of time (1hr+)")
# Call the function
# gen_uv_test = function(df, nfcst, tau, no_run = c(0,0,0,0)){
# print(head(pc_df))
uv_list = gen_uv_test(df = pc_df, nfcst = ntest, tau = tau, no_run = no_run)
# Add to a data frame
# Incorporate the rolling predictions function results here
plot_mat = cbind(pc_df[(test_orig+1):nrow(pc_df),1], mv_fcst$yhat[1:ntest], mv_fcst_art1$yhat[1:ntest], mv_fcst_art2$yhat[1:ntest], mv_fcst_art3$yhat[1:ntest], uv_list[[1]][(test_orig+1):test_end]*(-1), uv_list[[2]][(test_orig+1):test_end]*(-1), uv_list[[3]][(test_orig+1):test_end]*(-1), uv_list[[4]][(test_orig+1):test_end]*(-1))
} else {
# Assign the columns of the data frame
# head(var_5pc_2010_usetf[[1]][,6:9])
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# test_df = head(var_5pc_2010_usetf[[1]][,6:9])
# test_df$SAV
# test_df$`Abs. Slope`
# test_df$`Ind. GARCH`
# test_df$Adaptive
plot_mat = cbind(pc_df[(test_orig+1):nrow(pc_df),1], mv_fcst$yhat[1:ntest], mv_fcst_art1$yhat[1:ntest], mv_fcst_art2$yhat[1:ntest], mv_fcst_art3$yhat[1:ntest], uv_list$SAV, uv_list$`Abs. Slope`, uv_list$`Ind. GARCH`, uv_list$Adaptive)
}
# Count the NAs and print a warning
print(paste("NOTE: There are ", sum(is.na(plot_mat)), " NA(s) in the dataset", sep = ""))
# Linearly interpolate the NAs
if (na_interp == TRUE){
# Assign the plot matrix to a new value
plot_mat_na <- plot_mat
# Print a warning
print("WARNING: There were missing values in the plot matrix.")
# Interpolate the NA's
for (i in 1:ncol(plot_mat_na)){
# Interpolate the data
plot_mat[,i] <- na.approx(plot_mat_na[,i])
}
}
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# Add descriptive titles onto the plot_mat
colnames(plot_mat) <- c(resp_var, "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")
# colnames(plot_mat) <- c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")
# Plot everything
plot = plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# Calculate losses
l_list = gen_loss_test(plot_mat, tau = tau)
# Put into tables
tables = pretty_tables(plot_mat, l_list, tau = tau, ntest = ntest)
# Run the function for optimal p and m
pm_table = pretty_pm(opt_pred_nl[[3]], opt_pred_art1[[4]], opt_pred_art2[[4]], opt_pred_art3[[4]])
# Export the matrix
if (export_csv == 1){
exp_func(var_file = plot_mat, path, filename)
}
# Print the tables and the plot
print(plot)
print(tables)
print(pm_table)
return(list(plot_mat, plot, l_list, tables, plot_mat_na, pm_table))
}
#' A function to input the VaR files, plot them and generate tables
#'
#' @param file_path - file path to use
#' @param filename - name of the file
#' @param tau - quantile to use
#' @param resp_var - response variable to use in the plot
#' @param ntest - number of test points
#' @param cn_input - column name inputs
#'
#' @return - a list of the xts file, the plot, the loss list, and tables
#' @export - a plot and tables
#'
#' @examples - test = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2008_us_etf.csv", 0.01)
var_input_disp = function(file_path, filename, tau, resp_var = "SPY", ntest = 250, cn_input = c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")){
# var_input_disp = function(file_path, filename, tau, resp_var = "SPY", ntest = 250, cn_input = c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")){
# Import data
plot_mat = read.csv(paste0(file_path,filename), sep = ",", header = T, stringsAsFactors = FALSE)
# Fix date format
plot_mat$Index = as.Date(plot_mat$Index)
# Convert to an xts
plot_mat = xts(plot_mat[,-1], order.by = plot_mat[,1])
# Fix column names
colnames(plot_mat) <- cn_input
# Plot everything
plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# plot = plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# Calculate losses
l_list = gen_loss_test(plot_mat, tau = tau)
# Put into tables
df = as.data.frame(rbind(l_list[[1]], l_list[[2]]))
# Calculate inital and ending time value
start = index(plot_mat)[1]
end = index(plot_mat)[nrow(plot_mat)]
# Add row/column names
colnames(df) <- colnames(plot_mat[,-1])
rownames(df) <- c("Losses", "VaR Breaks (%)")
# Convert to a table
print(df, digits = 3)
# print(formattable(df, digits = 3))
# df %>% kable(caption = paste("Comparison of VaR Methods for a ", tau*100, "% VaR", sep = ""), digits = 3) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = paste("Calculated using", ntest, "trading days from", as.Date(start), "to", as.Date(end)))
# pm_table = pretty_tables(plot_mat, l_list, tau = tau, ntest = ntest)
# Print the tables and the plot
# print(plot)
# print(tables)
# print(pm_table)
# Return the xts, the plot, the loss list, and the tables
return(list(plot_mat))
# return(list(plot_mat, plot, l_list, tables))
}
# return(list(plot_mat, plot, l_list, tables))
# Call the above function
v1_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2008_us_etf.csv", 0.01)
# pretty_tables(v1_2008_usetf[[1]], v1_2008_usetf[[3]], tau = 0.01, ntest = 250)
v5_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2008_us_etf.csv", 0.05)
v10_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2008_us_etf.csv", 0.10)
# head(v10_2008_usetf[[1]])
# v10_2008_usetf
# 1%, 5%, 10% VaR - 2008 - 1st set of predictors
# var_1pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2008_us_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2008_us_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2008_us_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2008_glob_etf.csv", 0.01)
v5_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2008_glob_etf.csv", 0.05)
v10_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2008_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2008 - 2nd set of predictors
# var_1pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2008_glob_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2008_glob_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2008_glob_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# 1%, 5%, 10% VaR - 2008 - 3rd set of predictors
# var_1pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2008_comm_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2008_comm_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2008_comm_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2008_bond_etf.csv", 0.01)
v5_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2008_bond_etf.csv", 0.05)
v10_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2008_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2008 - 4th set of predictors
# var_1pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2008_bond_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2008_bond_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2008_bond_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2008_all_etf.csv", 0.01)
v5_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2008_all_etf.csv", 0.05)
v10_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2008_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2008 - 5th set of predictors
# var_1pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2008_all_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2008_all_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2008_all_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2010_us_etf.csv", 0.01)
v5_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2010_us_etf.csv", 0.05)
v10_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2010_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 1st set of predictors
# var_1pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2010_us_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2010_us_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2010_us_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2010_glob_etf.csv", 0.01)
v5_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2010_glob_etf.csv", 0.05)
v10_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2010_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 2nd set of predictors
# var_1pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2010_glob_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2010_glob_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2010_glob_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# 1%, 5%, 10% VaR - 2010 - 3rd set of predictors
# var_1pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2010_comm_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2010_comm_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2010_comm_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2010_bond_etf.csv", 0.01)
v5_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2010_bond_etf.csv", 0.05)
v10_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2010_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2010 - 4th set of predictors
# var_1pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2010_bond_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2010_bond_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2010_bond_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2010_all_etf.csv", 0.01)
v5_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2010_all_etf.csv", 0.05)
v10_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2010_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 5th set of predictors
# var_1pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2010_all_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2010_all_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2010_all_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2014_us_etf.csv", 0.01)
v5_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2014_us_etf.csv", 0.05)
v10_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2014_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 1st set of predictors
# var_1pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2014_us_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2014_us_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2014_us_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2014_glob_etf.csv", 0.01)
v5_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2014_glob_etf.csv", 0.05)
v10_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2014_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 2nd set of predictors
# var_1pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2014_glob_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2014_glob_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2014_glob_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# 1%, 5%, 10% VaR - 2014 - 3rd set of predictors
# var_1pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2014_comm_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2014_comm_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2014_comm_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2014_bond_etf.csv", 0.01)
v5_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2014_bond_etf.csv", 0.05)
v10_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2014_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2014 - 4th set of predictors
# var_1pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2014_bond_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2014_bond_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2014_bond_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2014_all_etf.csv", 0.01)
v5_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2014_all_etf.csv", 0.05)
v10_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2014_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 5th set of predictors
# var_1pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2014_all_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2014_all_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2014_all_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2016_us_etf.csv", 0.01)
v5_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2016_us_etf.csv", 0.05)
v10_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2016_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 1st set of predictors
# var_1pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2016_us_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2016_us_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2016_us_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2016_glob_etf.csv", 0.01)
v5_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2016_glob_etf.csv", 0.05)
v10_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2016_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 2nd set of predictors
# var_1pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2016_glob_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2016_glob_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2016_glob_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# 1%, 5%, 10% VaR - 2016 - 3rd set of predictors
# var_1pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2016_comm_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2016_comm_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2016_comm_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2016_bond_etf.csv", 0.01)
v5_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2016_bond_etf.csv", 0.05)
v10_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2016_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2016 - 4th set of predictors
# var_1pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2016_bond_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2016_bond_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2016_bond_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2016_all_etf.csv", 0.01)
v5_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2016_all_etf.csv", 0.05)
v10_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2016_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 5th set of predictors
# var_1pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2016_all_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2016_all_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2016_all_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
LS0tCnRpdGxlOiAiTXVsdGl2YXJpYXRlIENBVmlhUiIKc3VidGl0bGU6ICJBbiBJbnNpZ2h0ZnVsIEFwcHJvYWNoIHRvIFJpc2sgTW9kZWxpbmciCmF1dGhvcjogIlN0ZXZlbiBNb2VuIgpkYXRlOiAiV2VkbmVzZGF5LCBNYXkgNnRoLCAyMDIwIgpvdXRwdXQ6CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdApiaWJsaW9ncmFwaHk6IHRoZXNpc19iaWJsaW9ncmFwaHkuYmliCmxpbmstY2l0YXRpb25zOiB5ZXMKCi0tLQoKYGBge3IgZ2xvYmFsX29wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9OCwgZmlnLnBhdGg9J0ZpZ3MvJywKICAgICAgICAgICAgICAgICAgICAgIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlID0gVFJVRSkKYGBgCgojIEFic3RyYWN0CgpUaGlzIHRoZXNpcyBidWlsZHMgdXBvbiBwcmV2aW91cyBsaXRlcmF0dXJlIGZvciBtb2RlbGluZyB2YWx1ZS1hdC1yaXNrIChkZWZpbmVkIGFzIGFuIHglIHF1YW50aWxlIG9mIGFuIGFzc2V0J3MgZGFpbHkgcmV0dXJucykgdXNpbmcgbm9uLWxpbmVhciBBUk1BIHRlcm1zIGJ5IGFkZGluZyBleGNoYW5nZS10cmFkZWQgZnVuZHMgKEVURnMpIGFzIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyB0aGF0IGFyZSBjb21iaW5lZCBpbnRvIHByaW5jaXBhbCBjb21wb25lbnQgdmVjdG9ycyBhdCB0aGUgZm9yZWNhc3Qgb3JpZ2luLiBDb21iaW5pbmcgdGhlc2UgcHJpbmNpcGFsIGNvbXBvbmVudCB2ZWN0b3JzIHdpdGggdHJhbnNmb3JtYXRpb25zIG9mIGxhZ2dlZCBhdXRvcmVncmVzc2l2ZSByZXNwb25zZSB2YXJpYWJsZXMgcmVzdWx0cyBpbiBhIG1vZGVsIHRoYXQgcHJvZHVjZXMgc2ltaWxhciBwcmVkaWN0aXZlIGFjY3VyYWN5IGR1cmluZyBwZXJpb2RzIG9mIHJlbGF0aXZlbHkgbG93IHZvbGF0aWxpdHkgYWxvbmcgd2l0aCBtb3JlIGluc2lnaHQgaW50byB0aGUgZHJpdmVycyBvZiB0aGUgY2hhbmdlcyBpbiB0aGUgcmVzcG9uc2UgdmFyaWFibGUuIEluIGZhY3QsIG9uZSBpbnNpZ2h0IGdhaW5lZCBmcm9tIHRoZSBuZXcgbW9kZWwgaXMgYSBtZXRob2Qgb2YgZGV0ZWN0aW5nIGNoYW5nZXBvaW50cyBpbiB0aGUgZWNvbm9teSBieSBtZWFzdXJpbmcgdGhlIGFuZ2xlIGJldHdlZW4gcmVzdWx0YW50IHZlY3RvcnMgY2FsY3VsYXRlZCBmcm9tIHRoZSBjb21iaW5hdGlvbiBvZiBwcmluY2lwYWwgY29tcG9uZW50IHZlY3RvcnMgZHVyaW5nIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMuIFRoaXMgbWV0aG9kLCBhbG9uZyB3aXRoIGFuYWx5c2lzIG9mIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIGxhZ2dlZCBFVEZzLCBhbGxvd3MgZm9yIGluc2lnaHQgaW50byBjaGFuZ2VzIGluIHRoZSB1bmRlcmx5aW5nIGVjb25vbXkuCgojIEJhY2tncm91bmQgYW5kIEludHJvZHVjdGlvbgoKV2hlbiBtb2RlbGluZyBmaW5hbmNpYWwgdGltZSBzZXJpZXMsIHNpbXBseSBjb25zaWRlcmluZyB0aGUgbWVhbiBhbmQgdGhlIHZhcmlhbmNlIGlzIGluc3VmZmljaWVudCBmb3IgYW4gYWNjdXJhdGUgZGVwaWN0aW9uIG9mIHRoZSByZXR1cm5zIC0gc3RvY2sgcmV0dXJucyBhcmUgd2VsbC1rbm93biBmb3IgaGF2aW5nIGZhdCB0YWlscyBhbmQgYXJlIGRpZmZpY3VsdCB0byBtb2RlbCB1c2luZyBhIG5vcm1hbCBkaXN0cmlidXRpb24gW0BGYW1hMTk2NV0uIEluIGZhY3QsIG1vZGVsaW5nIGEgMSUgb3IgYSA1JSBxdWFudGlsZSBvZiBkYWlseSByZXR1cm5zIGlzIGEgYmV0dGVyIHdheSB0byB1bmRlcnN0YW5kIGFuZCBwcmVkaWN0IHdoYXQgaGFwcGVucyBvbiB0aGUgd29yc3QgdHJhZGluZyBkYXlzIGFuZCB0byBnaXZlIGEgY2xlYXJlciBwaWN0dXJlIG9mIHdoYXQgbWlnaHQgaGFwcGVuIGR1cmluZyBhIGRvd250dXJuLiBJbmRlZWQsIGZpbmFuY2UgdGhlb3J5IHN1Z2dlc3RzIHRoYXQgYSBwcmltYXJ5IHJlYXNvbiB3aHkgdGhlIFMmUCA1MDAsIHdoaWNoIGlzIGEgbWFya2V0LWNhcGl0YWxpemF0aW9uIHdlaWdodGVkIGluZGV4IGNvbXBvc2VkIG9mIHRoZSA1MDAtbGFyZ2VzdCBwdWJsaWNseSB0cmFkZWQgY29tcGFuaWVzIGluIHRoZSBVbml0ZWQgU3RhdGVzLCBoYXMgZWFybmVkIGEgNi44JSBpbmZsYXRpb24tYWRqdXN0ZWQgcHJlLXRheCByZXR1cm4gd2l0aCBkaXZpZGVuZCByZWludmVzdG1lbnQgZnJvbSBKYW51YXJ5IDE4NzEgdGhyb3VnaCBBcHJpbCAyMDIwIFtAUEsyMDE5XSBpcyBiZWNhdXNlIG9mIHRoZSByaXNrIG9mIGEgc2lnbmlmaWNhbnQgZG93bnR1cm4uIEtlcnJ5IFBlY2h0ZXIgYXQgRm9yYmVzIGRlc2NyaWJlcyBpdCBhcyBhIHByZW1pdW0gZm9yIHRoZSBmYWN0IHRoYXQgInN0b2NrcyBhcmUgcmlza2llciIgYW5kICJtb3JlIHByb25lIHRvIHByaWNlIGZsdWN0dWF0aW9ucyBpbiB0aGUgc2hvcnQgcnVuIiBjb21wYXJlZCB0byBsb3dlciByaXNrIGludmVzdG1lbnRzIFtAUGVjaHRlcjIwMjBdLiBBIHBvcnRmb2xpbyBtYW5hZ2VyIG11c3QgaW5kZWVkIGNvbnNpZGVyIHRoZSBsb25nLXJ1biBwaWN0dXJlOyBhIHNtYWxsIGRpZmZlcmVuY2UgaW4gdGhlIGFubnVhbCByYXRlIG9mIHJldHVybiBjYW4gbWFrZSBhbiBlbm9ybW91cyBkaWZmZXJlbmNlIGluIHRoZSBlbmRpbmcgdmFsdWUgb2YgaW52ZXN0bWVudHMuIEhvd2V2ZXIsIGZvY3VzaW5nIGVudGlyZWx5IG9uIGxvbmctcnVuIHZhbHVlIGdlbmVyYXRpb24gaXMgbm90IHRoZSBvbmx5IGNvbnNpZGVyYXRpb24gYSBwcnVkZW50IG1hbmFnZXIgb3VnaHQgdG8gbWFrZS4gV2hpbGUgZm9yZWNhc3Rpbmcgc3RvY2sgcmV0dXJucyBpbiB0aGUgbG9uZy1ydW4gaXMgY2hhbGxlbmluZywgdGhlIHBlcmZvcm1hbmNlIG9mIGluZGljaWVzIHN1Y2ggYXMgdGhlIFMmUCA1MDAsIGRlc3BpdGUgc2VlbWluZ2x5IGV4aXN0ZW50aWFsIHRocmVhdHMgc3VjaCBhcyB0aGUgV29ybGQgV2FycyBhbmQgdGhlIEdyZWF0IERlcHJlc3Npb24sIGRvZXMgZ2l2ZSBzb21lIGNvbmZpZGVuY2UgdG8gaW52ZXN0b3JzIHdobyB0cnkgdG8gZm9jdXMgb24gbG9uZy1ydW4gdmFsdWUgZ2VuZXJhdGlvbi4gSWdub3JpbmcgdGhlIHNob3J0LXJ1biByZW1pbmRzIG9uZSBvZiBKb2huIE1heW5hcmQgS2V5bmVzJyBmYW1vdXMgbWF4aW0gdGhhdCB0aGUgImxvbmcgcnVuIGlzIGEgbWlzbGVhZGluZyBndWlkZSB0byBjdXJyZW50IGFmZmFpcnMiIGJlY2F1c2UgImluIHRoZSBsb25nIHJ1biB3ZSBhcmUgYWxsIGRlYWQiIFtAS2V5bmVzMTkyM10sIGFuZCBtb3Jlb3ZlciwgdGhlIHNob3J0LXJ1biBpbXBhY3Qgb2YgYSBzdHJhdGVneSBpcyBvZnRlbiBtb3JlIGRpZmZpY3VsdCB0byB1bmRlcnN0YW5kIHRoYW4gdGhlIGxvbmctcnVuIHJlc3VsdHMsIGFuZCBwb3RlbnRpYWxseSBtb3JlIHByZWNhcmlvdXMuIEFuIGludmVzdG1lbnQgbWFuYWdlciB1c2luZyBmaW5hbmNpYWwgbGV2ZXJhZ2UgdG8gbWFnbmlmeSByZXR1cm5zIChwb3NpdGl2ZSBvciBuZWdhdGl2ZSkgY291bGQgYmUgbGVmdCBpbiBkaXJlIHN0cmFpdHMgaWYgdGhlaXIgaW52ZXN0bWVudHMgZmVsbCByYXBpZGx5LCBkZXNwaXRlIGEgc291bmQgbG9uZy1ydW4gc3RyYXRlZ3kuCgpXaGlsZSB0aGVyZSBhcmUgb3RoZXIgd2F5cyB0byB1bmRlcnN0YW5kIGFuZCBtZWFzdXJlIGRvd25zaWRlIHJpc2ssIGEgY29tbW9ubHkgYWNjZXB0ZWQgbWV0aG9kIGlzIHVzaW5nIHZhbHVlLWF0LXJpc2sgKFZhUikuIFRoZSBtZXRyaWMgaXMgdW5kZXJzdG9vZCBhcyBmb2xsb3dzOiBhIG9uZS1kYXkgMSUgVmFSIG9mIC0xMCUgZm9yIGEgcG9ydGZvbGlvIG1lYW5zIHRoYXQgdGhlIHBvcnRmb2xpbyB3aWxsIGxvc2UgYXQgbGVhc3QgMTAlIG9mIGl0cyB2YWx1ZSBvbiB0aGUgMSUgd29yc3QgdHJhZGluZyBkYXlzLiBBIG1ham9yIGFkdmFudGFnZSBvZiBWYVIgaXMgdGhhdCBpdCBkaXN0aWxscyBhIGRpc3RyaWJ1dGlvbiBvZiByZXR1cm5zIGludG8gb25lIG51bWJlci4gQXMgc3VjaCwgVmFSIGlzIG9mdGVuIHVzZWQgaW4gc3RyZXNzIHRlc3RpbmcgYnkgcmVndWxhdG9yeSBhZ2VuY2llcyBpbiB0aGUgVW5pdGVkIFN0YXRlcywgdGhlIFVuaXRlZCBLaW5nZG9tLCBhbmQgRXVyb3BlW0BIb2x0b24yMDE0XS4KCk1hbnkgb2YgdGhlIGFwcHJvYWNoZXMgZm9yIG1vZGVsaW5nIFZhUiByZWx5IG9uIGEgc2VtaXBhcmFtZXRyaWMgb3IgYSBub25wYXJhbWV0cmljIGhpc3RvcmljYWwgc2ltdWxhdGlvbiBbQFJpY2hhcmRzb24yMDA1XS4gQWNjb3JkaW5nIHRvIFJvYmVydCBFbmdsZSBhbmQgU2ltb25lIE1hbmdhbmVsbGkgaW4gYSAyMDA0IHBhcGVyLCB0aGVzZSBtZXRob2RzIGFyZSB1c3VhbGx5IGNob3NlbiBmb3Ig4oCcZW1waXJpY2FsIGp1c3RpZmljYXRpb25zIHJhdGhlciB0aGFuIG9uIHNvdW5kIHN0YXRpc3RpY2FsIHRoZW9yeeKAnSBbQEVuZ2xlMjAwNF0uIFRoZXkgcHJvcG9zZSBhIGZyYW1ld29yayBjYWxsZWQgQ0FWaWFSIHRoYXQgZGlyZWN0bHkgZm9yZWNhc3RzIHRoZSBWYVIgcXVhbnRpbGUgZGlyZWN0bHkgdXNpbmcgYSBjb25kaXRpb25hbCBhdXRvcmVncmVzc2l2ZSBxdWFudGlsZSBzcGVjaWZpY2F0aW9uLiBUaGlzIGFwcHJvYWNoIGJ1aWxkcyB1cG9uIHRoZSBzdGF0aXN0aWNhbCBsaXRlcmF0dXJlIHRoYXQgZXh0ZW5kcyBsaW5lYXIgcXVhbnRpbGUgbW9kZWxzIHRvIHNldHRpbmdzIGFtZW5hYmxlIHRvIGZpbmFuY2lhbCBtb2RlbGluZywgc3VjaCBhcyB3aXRoIGhldGVyb3NrZWRhc3RpYyBhbmQgbm9uc3RhdGlvbmFyeSBlcnJvciBkaXN0cmlidXRpb25zIFtAUG9ydG5veTE5OTFdLgoKIyBNZXRob2RzIFVzZWQKCkEgY29tbW9uIHByb2JsZW0gaW4gc3RhdGlzdGljYWwgYW5hbHlzaXMgb2NjdXJzIHdoZW4gYSB0cmFpbmluZyBzYW1wbGUgaXMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSB0aGF0IG9mIHRoZSB0ZXN0IHNhbXBsZS4gSW5pdGlhbCBtb3RpdmF0aW9ucyBmb3IgdGhpcyBwYXBlciBpbnZvbHZlZCBhbmFseXppbmcgdHdvIHN0b2NrcyAtIEFtYXpvbiAodGlja2VyOiBBTVpOKSBhbmQgUHJvY3RvciAmIEdhbWJsZSAodGlja2VyOiBQRykgYW5kIHRoZWlyIHBlcmZvcm1hbmNlIGR1cmluZyB0aGUgR3JlYXQgUmVjZXNzaW9uIChzcGVjaWZpY2FsbHksIHRoZSBsYXN0IDIwMCB0cmFkaW5nIGRheXMgb2YgMjAwOCkuIEEgcmVsZXZhbnQgcXVlc3Rpb24gb2YgYSBmaW5hbmNpYWwgaW5zdGl0dXRpb24gd291bGQgdW5kZXJzdGFuZGFibHkgYmUgaG93IHRoZWlyIHJpc2sgbW9kZWwgcGVyZm9ybWVkIGR1cmluZyAyMDA4LCBhIGhpZ2hseSB2b2xhdGlsZSBwZXJpb2Qgd2hpY2ggd2FzIGRyaXZlbiBieSB0aGUgIm1vc3Qgc2V2ZXJlIGZpbmFuY2lhbCBjcmlzaXMgc2luY2UgdGhlIEdyZWF0IERlcHJlc3Npb24iLCBhY2NvcmRpbmcgdG8gR2FyeSBCZWNrZXIgW0BCZWNrZXIyMDA4XSwgYSBOb2JlbC1wcml6ZSB3aW5uaW5nIGVjb25vbWlzdC4gSW50ZXJlc3RpbmdseSwgdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIGZvcmVjYXN0IGZvciBBbWF6b24gd2FzIGZhaXJseSBhY2N1cmF0ZSB3aGVyZWFzIHRoZSBmb3JlY2FzdCBmb3IgUEcgd2FzIG5vdC4gT25lIHJlYXNvbiBmb3IgdGhpcyBjb3VsZCBiZSB0aGUgZmFjdCB0aGF0IGEgc3RvY2sgbGlrZSBBbWF6b24gd2FzIGhpZ2hseSB2b2xhdGlsZSBkdXJpbmcgdGhlIHRyYWluaW5nIHNhbXBsZSwgd2hpY2ggaW5jbHVkZWQgcmV0dXJuIGRhdGEgc3RhcnRpbmcgZnJvbSB0aGUgMm5kIHF1YXJ0ZXIgb2YgMjAwNCwgYnV0IFBHIHdhcyBmYWlybHkgc3RhYmxlLiBIb3cgd291bGQgaXQgYmUgcG9zc2libGUgZm9yIGEgdW5pdmFyaWF0ZSBtb2RlbCBzdWNoIGFzIENBVmlhUiwgdGhhdCBkb2VzIG5vdCBleHBsaWNpdGx5IGFjY291bnQgZm9yIG90aGVyIGZhY3RvcnMsIHRvIGZvcmVjYXN0IHdlbGw/IFdoYXQgaWYgYSB2b2xhdGlsZSBzdG9jayBzdWNoIGFzIEFNWk4gd2FzIGluY2x1ZGVkIGludG8gdGhlIGZvcmVjYXN0IGZvciBQRyAtIHdvdWxkIGl0IGltcHJvdmUgdGhlIHByZWRpY3Rpb24/CgpUaHVzLCB0aGUgaWRlYSBvZiBjb21iaW5pbmcgc3RvY2tzIGludG8gYSBtdWx0aXZhcmlhdGUgc2V0dGluZyB0byBjYXB0dXJlIGNvcnJlbGF0aW9ucyBhbmQgYmV0dGVyIGZvcmVjYXN0IHJpc2sgd2FzIGZvcm1lZC4gQSBuYXR1cmFsIGNob2ljZSBhcHBlYXJlZCB0byBiZSB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsLCBvcmlnaW5hbGx5IGRldmVsb3BlZCBieSBTdG9jayBhbmQgV2F0c29uIGZvciBwcmVkaWN0aW5nIGNvbmRpdGlvbmFsIG1lYW5zIFtAU3RvY2syMDAyOyBAU3RvY2syMDAyYV0uIFRoZSBtb2RlbCBmb3IgZm9yZWNhc3RpbmcgdGhlIGNvbmRpdGlvbmFsIG1lYW4gaXMgc3BlY2lmaWVkIGJlbG93LgoKIyMgRGlmZnVzaW9uIEluZGV4IE1vZGVsCgpBIHVzZWZ1bCBtZWFucyBvZiBwcmVkaWN0aW5nIHN0b2NrIG1vdmVtZW50cyBpbiB0aGUgZnV0dXJlIGlzIHRoZSBTdG9jayBhbmQgV2F0c29uIGRpZmZ1c2lvbiBpbmRleC4gVGhlIG1vZGVsIGlzIG91dGxpbmVkIGJlbG93LCB3aGljaCBpcyBhZGFwdGVkIGZyb20gTXVsdGl2YXJpYXRlIFRpbWUgU2VyaWVzIEFuYWx5c2lzIFdpdGggUiBhbmQgRmluYW5jaWFsIEFwcGxpY2F0aW9ucyBieSBSdWV5IFMuIFRzYXkgW0BUc2F5MjAxNF0uCgpUaGVyZSBhcmUgdHdvIHJlbGV2YW50IGVxdWF0aW9uczoKCiQkClxib2xkc3ltYm9se3pfdH0gPSBcYm9sZHN5bWJvbHtMZl90fSArIFxib2xkc3ltYm9se1xlcHNpbG9uX3R9CiQkCgphbmQgCgokJAp5X3t0K2h9ID0gXGJvbGRzeW1ib2x7XGJldGFeXHByaW1lIGZfdH0gKyBcYm9sZHN5bWJvbHtlX3t0K2h9fQokJAoKSW4gdGhlIGZpcnN0IGVxdWF0aW9uICRcYm9sZHN5bWJvbHt6X3R9ID0gKHpfezF0fSwgLi4uLiwgel97a3R9KV5ccHJpbWUkIGlzIGFuIG9ic2VydmVkIHRpbWUgc2VyaWVzIHdpdGggbWVhbiAwLCAkXGJvbGRzeW1ib2x7Zl90fSQgaXMgYW4gbS1kaW1lbnNpb25hbCB2ZWN0b3Igb2YgY29tbW9uIGZhY3RvcnMgd2l0aCBtZWFuIDAgYW5kIGlkZW50aXR5IGNvdmFyaWFuY2UgbWF0cml4LCAkXGJvbGRzeW1ib2x7TH0kIGlzIGEgJGskIHggJG0kIGxvYWRpbmcgbWF0cml4LCBhbmQgJFxib2xkc3ltYm9se1xlcHNpbG9uX3R9JCBpcyBhbiBpbmRlcGVuZGVudCBhbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgKGkuaS5kLikgc2VxdWVuY2Ugb2YgcmFuZG9tIHZlY3RvcnMgd2l0aCBtZWFuIDAgYW5kIGNvdmFyaWFuY2UgbWF0cml4ICRcYm9sZHN5bWJvbHtcU2lnbWFfZX0kLgoKSW4gdGhlIHNlY29uZCBlcXVhdGlvbiwgd2hpY2ggcmVwcmVzZW50cyB0aGUgaC1zdGVwIGFoZWFkIHByZWRpY3Rpb24gYmFzZWQgb24gJFxib2xkc3ltYm9se2ZfdH0kLCAkeV90JCBpcyB0aGUgc2NhbGFyIHRpbWUgc2VyaWVzIG9mIGludGVyZXN0LCAkaCQgaXMgdGhlIGZvcmVjYXN0IGhvcml6b24sICRcYm9sZHN5bWJvbHtcYmV0YX0kIHJlcHJlc2VudHMgdGhlIHZlY3RvciBvZiBjb2VmZmljaWVudHMsIGFuZCAkZV90JCBpcyBhIHNlcXVlbmNlIG9mIHVuY29ycmVsYXRlZCByYW5kb20gdmFyaWFibGVzIHdpdGggbWVhbiAwIGFuZCBjb25zdGFudCB2YXJpYW5jZS4gCgpUbyBtb2RlbCB0aGUgZGF0YSwgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcyBpcyBwZXJmb3JtZWQgb24gdGhlIGNvdmFyaWF0ZXMgZGVzY3JpYmVkIGJlbG93IHRvIG9idGFpbiBhbiBlc3RpbWF0ZSBvZiAkXGJvbGRzeW1ib2x7Zl90fSQuIFRoZW4gdGhlICRcYm9sZHN5bWJvbHtcYmV0YX0kIGNvZWZmaWNpZW50cyBhcmUgZXN0aW1hdGVkIHVzaW5nIG9yZGluYXJ5IGxlYXN0IHNxdWFyZXMuCgojIyBVbml2YXJpYXRlIENBVmlhUiBNb2RlbCBTcGVjaWZpY2F0aW9ucwoKSG93ZXZlciwgd29yayBuZWVkZWQgdG8gYmUgZG9uZSB0byBhbGlnbiB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsIHdpdGggdGhlIENBVmlhUiBtb2RlbCwgd2hpY2ggaXMgZGVmaW5lZCBiZWxvdy4gVGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgYXJlIHJlcXVpcmVkIGZvciB1c2UgaW4gdGhlIENBVmlhUiBtb2RlbDoKCltERVNDUklQVElPTiBPRiBWQVJJQUJMRVNdCgojIyMgQWRhcHRpdmUgQ0FWaWFSIE1vZGVsCgokJApmX3QoXGJldGFfMSkgPSBmX3t0LTF9KFxiZXRhXzEpICsgXGJldGFfMVxsZWZ0W1xsZWZ0KDErIFxleHAoR1t5X3t0LTF9IC0gZl97dC0xfShcYmV0YV8xKV0pICBccmlnaHQpXnstMX0gLSBcdGhldGEgXHJpZ2h0XSAKJCQKCiMjIyBTeW1tZXRyaWMgQWJzb2x1dGUgVmFsdWUgQ0FWaWFSIE1vZGVsCgokJApmX3QoXGJvbGRzeW1ib2x7XGJldGF9KSA9IFxiZXRhXzEgKyBcYmV0YV8yZl97dC0xfShcYm9sZHN5bWJvbHtcYmV0YX0pICsgXGJldGFfM3x5X3t0LTF9fAokJAoKIyMjIEFzeW1tZXRyaWMgU2xvcGUgQ0FWaWFSIE1vZGVsCgokJApmX3QoXGJvbGRzeW1ib2x7XGJldGF9KSA9IFxiZXRhXzEgKyBcYmV0YV8yZl97dC0xfShcYm9sZHN5bWJvbHtcYmV0YX0pICsgXGJldGFfMyh5X3t0LTF9KV4rICsgXGJldGFfNCh5X3t0LTF9KV4tCiQkCgojIyMgSW5kaXJlY3QgR0FSQ0ggKDEsMSkgQ0FWaWFSIE1vZGVsCgokJApmX3QoXGJvbGRzeW1ib2x7XGJldGF9KSA9IChcYmV0YV8xICsgXGJldGFfMmZfe3QtMX1eMihcYm9sZHN5bWJvbHtcYmV0YX0pICsgXGJldGFfM3lfe3QtMX1eMileezEvMn0KJCQKCiMjIE11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWwgU3BlY2lmaWNhdGlvbnMKClRoZSBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVsIHRha2VzIGluc3BpcmF0aW9uIGZyb20gdGhlIG1vZGVscyBkZXNjcmliZWQgYWJvdmUgaW4gc2V2ZXJhbCBzcGVjaWZpY2F0aW9ucy4gVGhlIGdlbmVyYWwgbW9kZWwgZm9ybSBsb29rcyBsaWtlIHRoZSBzcGVjaWZpY2F0aW9uIGJlbG93LgoKVkFSID0gSU5URVJDRVBUICsgUEFTVCBWQUxVRVMgKyBBUiBDT01QT05FTlQgKyBFUlJPUgoKIyMjIE11bHRpdmFyaWF0ZSBDQVZpYVI6IE5vIExhZ3MgTW9kZWwKClZBUiA9IElOVEVSQ0VQVCArIFBBU1QgVkFMVUVTICsgRVJST1IKCiMjIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIHdpdGggQXV0b3JlZ3Jlc3NpdmUgVGVybXMgQWRkZWQKClZBUiA9IElOVEVSQ0VQVCArIFBBU1QgVkFMVUVTICsgQVIgQ09NUE9ORU5UICsgRVJST1IKCiMjIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIHdpdGggU3ltbWV0cmljIEFic29sdXRlIFZhbHVlIEF1dG9yZWdyZXNzaXZlIFRlcm1zIEFkZGVkCgpWQVIgPSBJTlRFUkNFUFQgKyBQQVNUIFZBTFVFUyArIFNBViBBUiBDT01QT05FTlQgKyBFUlJPUgoKIyMjIE11bHRpdmFyaWF0ZSBDQVZpYVIgd2l0aCBBc3ltbWV0cmljIFNsb3BlIEF1dG9yZWdyZXNzaXZlIFRlcm1zIEFkZGVkCgpWQVIgPSBJTlRFUkNFUFQgKyBQQVNUIFZBTFVFUyArIEFTIEFSIENPTVBPTkVOVCArIEVSUk9SCgoKIyMgRml0dGluZyB0aGUgTW9kZWxzCgpUbyBmaXQgdGhlIG1vZGVscywgYW4gb3B0aW1hbCB2YWx1ZSBvZiAkbSQgZGlmZnVzaW9uIGluZGljZXMgYW5kICRwJCBhdXRvcmVncmVzc2l2ZSB0ZXJtcyBhcmUgYWRkZWQgKG9yICQycCQgaW4gdGhlIGNhc2Ugb2YgdGhlIGFzeW1tZXRyaWMgc2xvcGUgbW9kZWwpLiBUaGUgb3B0aW1hbCB2YWx1ZXMgb2YgdGhlc2UgcGFyYW1ldGVycyBhcmUgZGV0ZXJtaW5lZCB1c2luZyBhIHZhbGlkYXRpb24gZGF0YXNldC4gSW4gYWxsIG9mIHRoZSBydW5zIGJlbG93LCB0aGVyZSBhcmUgYSB0b3RhbCBvZiA1IHllYXJzIG9mIHRyYWRpbmcgZGF5cywgb3IgYWJvdXQgMSwyNjAgZGF5cyBhc3N1bWluZyAyNTIgdHJhZGluZyBkYXlzIGEgeWVhci4gVGhlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzIGFyZSBsb2dnZWQgYW5kIGRpZmZlcmVuY2VkLCBzaG9ydGVuaW5nIHRoZSBkYXRhc2V0IGJ5IG9uZS4gQWZ0ZXIgZG9pbmcgdGhpcywgdGhlIGxhc3QgMjUwIGRhdGEgcG9pbnRzIGFyZSByZXNlcnZlZCBhcyB0ZXN0IGRhdGEsIGFuZCB0aGUgMjUwIGRhdGEgcG9pbnRzIGJlZm9yZSB0aGF0IGFyZSB1c2VkIGFzIGEgdmFsaWRhdGlvbiBzZXQuIE1lYXN1cmVkIGJ5IHRoZSBsb3NzIGZ1bmN0aW9uIHdyaXR0ZW4gb3V0IGJlbG93LCB0aGUgdmFsdWVzIG9mICRwJCBhbmQgJG0kIHRoYXQgbWluaW1pemUgbG9zc2VzIGFyZSBjaG9zZW4gYW5kIHRoZSBvcHRpbWFsIG1vZGVsIGlzIHJlZml0IG92ZXIgYm90aCB0aGUgdHJhaW5pbmcgYW5kIHRoZSB2YWxpZGF0aW9uIGRhdGEgY29tYmluZWQgYW5kIHRoZW4gZXZhbHVhdGVkIG9uIHRoZSB0ZXN0IGRhdGEuIE5vdGUgdGhhdCB0aGVyZSBpcyBhbiBvcHRpbWFsIG1vZGVsIGlzIGNob3NlbiBmb3IgZWFjaCBvZiB0aGUgZm91ciBtdWx0aXZhcmlhdGUgQ0FWaWFSIHNwZWNpZmljYXRpb25zIGRlc2NyaWJlZCBhYm92ZSwgc28gdGhlcmUgYXJlIDQgb3B0aW1hbCBzZXRzIG9mICRwJCBhbmQgJG0kIGNob3NlbiBmb3IgZWFjaCBzZXQgb2YgbW9kZWwuIFRodXMsIHRoZXJlIGFyZSA4IG1vZGVscyBjb21wYXJlZCBvbiB0aGUgdGVzdCBkYXRhIC0gNCB1bml2YXJpYXRlIENBVmlhUiBtb2RlbHMgYW5kIDQgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbHMuCgpbTE9TUyBGVU5DVElPTl0KCiMgRGF0YSBVc2VkCgpUaGUgcmVzcG9uc2UgdmFyaWFibGUgdXNlZCBpbiB0aGlzIGFuYWx5c2lzIGlzIFNQWSwgd2hpY2ggaXMgYW4gZXhjaGFuZ2UtdHJhZGVkIGZ1bmQgdGhhdCBhaW1zIHRvIHRyYWNrIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgUyZQIDUwMCwgd2hpY2ggaXMgZGlzY3Vzc2VkIGFib3ZlLiBJdCBpcyBicm9hZGx5IHVzZWQgYXMgYSBiZWxsd2V0aGVyIG9mIHRoZSBVLlMuIGVjb25vbXksIGFuZCBoYXMgdGhlIGFkdmFudGFnZSBvZiBhdm9pZGluZyBzdXJ2aXZvcnNoaXAgYmlhcyAtIHdoaWxlIGFuIGluZGl2aWR1YWwgc3RvY2sgbWlnaHQgZ28gYmFua3J1cHQgb3IgbWVyZ2Ugd2l0aCBhbm90aGVyLCBpdCdzIHJlYXNvbmFibGUgdG8gYXNzdW1lIHRoYXQgdGhlc2UgaXNzdWVzIGRvIG5vdCBhcHBseSB3aXRoIGFuIEVURi4gCgpGb2xsb3dpbmcgdGhpcyBsb2dpYywgdGhlcmUgYXJlIHNldmVyYWwgY2xhc3NlcyBvZiByZXNwb25zZSB2YXJpYWJsZXMgdXNlZCBpbiB0aGlzIGFuYWx5c2lzLiBUaGUgZmlyc3QgZ3JvdXAgaXMgYSBzZXQgb2YgVS5TLiBzZWN0b3IgRVRGcy4gQXMgd2l0aCB0aGUgcmVzcG9uc2UgdmFyaWFibGUsIHRoZXNlIEVURnMgd2VyZSBwdWJsaWNseSB0cmFkZWQgdGhyb3VnaG91dCB0aGUgR3JlYXQgUmVjZXNzaW9uIG9mIDIwMDguCgphLiBVdGlsaXRpZXMgKFhMVSkKYi4gQ29uc3VtZXIgU3RhcGxlcyAoWExQKQpjLiBIZWFsdGhjYXJlIChYTFYpCmQuIFRlY2hub2xvZ3kgKFhMSykKZS4gQ29uc3VtZXIgRGlzY3JldGlvbmFyeSAoWExZKQpmLiBJbmR1c3RyaWFsIChYTEkpCmcuIEZpbmFuY2lhbCBTZXJ2aWNlcyAoWExGKQpoLiBCYXNpYyBNYXRlcmlhbHMgKFhMQikKaS4gRW5lcmd5IChYTEUpCgpUaGUgc2Vjb25kIGdyb3VwIGlzIEdsb2JhbCBTZWN0b3IgRVRGcy4gVGhlIHJhdGlvbmFsZSBmb3IgaW5jbHVkaW5nIHRoZXNlIGlzIHRoYXQgcGVyaGFwcyBzb21lIGdsb2JhbCBleHBvc3VyZSBpcyB1c2VmdWwgaW4gdW5kZXJzdGFuZGluZyB0aGUgYnJvYWRlciBtYXJrZXQuCgphLiBVdGlsaXRpZXMgKEpYSSkKYi4gQ29uc3VtZXIgU3RhcGxlcyAoS1hJKQpjLiBIZWFsdGhjYXJlIChJWEopCmQuIFRlbGVjb21tdW5pY2F0aW9ucyAoSVhQKQplLiBUZWNobm9sb2d5IChJWE4pCmYuIENvbnN1bWVyIERpc2NyZXRpb25hcnkgKFJYSSkKZy4gSW5kdXN0cmlhbCAoRVhJKQpoLiBGaW5hbmNpYWwgU2VydmljZXMgKElYRykKaS4gQmFzaWMgTWF0ZXJpYWxzIChNWEkpCmouIEVuZXJneSAoSVhDKQoKVGhlIHRoaXJkIGdyb3VwIGlzIGJvbmQgRVRGcy4gTGlrZSB0aGUgcHJldmlvdXMgdHdvIGdyb3VwcywgdGhlc2UgRVRGcyBwb3RlbnRpYWxseSBjb250YWluIGZvcndhcmQtbG9va2luZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3RvY2sgbWFya2V0LiBMaW5rIGJlbG93OgoKYS4gaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKYi4gaVNoYXJlcyA3LTEwIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChJRUYpCmMuIGlTaGFyZXMgMjArIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChUTFQpCmQuIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKTGFzdGx5LCBhbGwgb2YgdGhlIGFib3ZlIHRocmVlIGdyb3VwcyBhcmUgcnVuIHRvZ2V0aGVyLiBJbiBlYWNoIHJ1biwgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBhcmUgbGFnZ2VkIHRvIGF2b2lkIGxvb2stYWhlYWQgYmlhcy4gQWxsIG9mIHRoZSBydW5zIGFuYWx5emUgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIGxvZyBvZiB0aGUgYWRqdXN0ZWQgY2xvc2luZyBwcmljZS4gVGhlIHJlYXNvbiBmb3IgdXNpbmcgdGhlIGRpZmZlcmVuY2VkIGxvZyBpcyB0aGF0IGl0IGNsb3NlbHkgYXBwcm94aW1hdGVzIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBvZiB0aGUgcHJpY2UgZm9yIHNtYWxsIGNoYW5nZXMuIFRoZSByZWFzb24gZm9yIHVzaW5nIHRoZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBpcyB0aGF0IGFuIGFkanVzdGVkIGNsb3NpbmcgcHJpY2UgZXhjbHVkZXMgdGhlIGVmZmVjdHMgb2YgImNvcnBvcmF0ZSBhY3Rpb25zIHN1Y2ggYXMgc3RvY2sgc3BsaXRzLCBkaXZpZGVuZHMgLyBkaXN0cmlidXRpb25zIGFuZCByaWdodHMgb2ZmZXJpbmdzIiBbQEdhbnQyMDE5XS4gV2hpbGUgZGl2aWRlbmRzIGFyZSBlc3NlbnRpYWwgdG8gc3R1ZHkgdGhlIGxvbmctdGVybSBwZXJmb3JtYW5jZSBvZiBhIHN0cmF0ZWd5LCBzdHVkeWluZyBzaG9ydC10ZXJtIHByaWNlIG1vdmVtZW50cyBkbyBub3QgcmVxdWlyZSB1bmRlcnN0YW5kaW5nIHRoZSBlZmZlY3RzIG9mIGRpdmlkZW5kIHJlaW52ZXN0bWVudC4KCiMgUmVzdWx0cwoKYGBge3J9CiMgUmVhZCBpbiByZWxldmFudCBsaWJyYXJpZXMKbGlicmFyeShtaWNyb2JlbmNobWFyaykKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHF1YW50bW9kKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodHNlcmllcykKbGlicmFyeSh6b28pCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShmb3JtYXR0YWJsZSkKbGlicmFyeShxdWFudHJlZykKbGlicmFyeShNVFMpCmxpYnJhcnkocGxvdDNEKQpsaWJyYXJ5KGNpdHIpCmxpYnJhcnkoZm9ybWF0dGFibGUpCgojIFNldCB1cCB3b3JraW5nIGRpcmVjdG9yeQojIHNldHdkKCJ+L0RvY3VtZW50cy9HaXRIdWIvQ2F2aWFSIikKCiMgc291cmNlKCdjYXZpYXJfU00uUicpCnNvdXJjZSgnfi9Eb2N1bWVudHMvR2l0SHViL0NhdmlhUi9jYXZpYXJfU00uUicpCmBgYAoKYGBge3J9CiMgVGhpcyBjb2RlIGJlbG93IGlzIGZvciB1c2UgaW4gdGhlIENBVmlhUiBzZWN0aW9ucy4KYGBgCgpgYGB7cn0KIyBIZXJlIGlzIGNvZGUgdGhhdCBJJ2xsIHdyYXAgc29tZSBwYXJ0cyBpbiB0byBhdm9pZCBzdXBlcmZsdW91cyBvdXRwdXQKcXVpZXQgPC0gZnVuY3Rpb24oeCkgeyAKICBzaW5rKHRlbXBmaWxlKCkpIAogIG9uLmV4aXQoc2luaygpKSAKICBpbnZpc2libGUoZm9yY2UoeCkpIAp9IApgYGAKCgpgYGB7cn0KIycgVGhpcyBpcyBhIGZ1bmN0aW9uIHdoaWNoIHB1bGxzIGRhdGEgZm9yIHVzZSBpbiB0aGUgQ0FWaWFSIG1vZGVsCiMnCiMnIEBwYXJhbSBzeW1ib2wgLSBzeW1ib2wgdG8gcHVsbAojJyBAcGFyYW0gY29tcGxfY2FzZSAtIGRlZmF1bHRzIHRvIHRydWUuLi5vbmx5IGluY2x1ZGVzIGNvbXBsZXRlIGNhc2VzIGluIHRoZSBkYXRhCiMnIEBwYXJhbSBhZGpfY2xvc2UgLSB1c2UgYWRqdXN0ZWQgY2xvc2luZyBwcmljZXMuIERlZmF1bHQgaXMgeWVzLgojJyBAcGFyYW0gbG9nX3JldHVybiAtIHVzZSBsb2cgcmV0dXJuPyBEZWZhdWx0IGlzIHllcy4KIycKIycgQHJldHVybiAtIGEgZGF0YSBmcmFtZSB3aGljaCBjYW4gYmUgZmVkIGludG8gbGF0ZXIgZnVuY3Rpb25zCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gZGF0YV9wdWxsKCJTUFkiKQpkYXRhX3B1bGwgPSBmdW5jdGlvbihzeW1ib2wsIGNvbXBsX2Nhc2UgPSAxLCBhZGpfY2xvc2UgPSAxLCBsb2dfcmV0dXJuID0gMSwgc3RhcnRfZGF0ZSA9ICIxOTAwLTAxLTAxIiwgZW5kX2RhdGUgPSBTeXMuRGF0ZSgpKXsKICAjIFB1bGwgaW4gZGF0YSBmcm9tIHF1YW50bW9kCiAgcmVzcG9uc2VfcHVsbCA9IGdldFN5bWJvbHMoc3ltYm9sLCBhdXRvLmFzc2lnbiA9IEZBTFNFLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKICAjIEdldCBhZGp1c3RlZCBjbG9zaW5nIHByaWNlCiAgaWYgKGFkal9jbG9zZSA9PSBUUlVFKXsKICAgIGRmID0gQWQocmVzcG9uc2VfcHVsbCkKICB9IGVsc2UgewogICAgZGYgPSBDbChyZXNwb25zZV9wdWxsKQogIH0KICAjIFJldHVybiBjb21wbGV0ZSBjYXNlcyBvbmx5IAogIGlmIChjb21wbF9jYXNlID09IFRSVUUpewogICAgZGYgPSBkZltjb21wbGV0ZS5jYXNlcyhkZiksIF0KICB9IGVsc2V7CiAgICBkZiA9IGRmCiAgfQogICMgQ2FsY3VsYXRlIGxvZyByZXR1cm4gb2YgZGF0YQogIGlmIChsb2dfcmV0dXJuID09IFRSVUUpewogICAgbHIgPSBsb2coZGZbLDFdL3NoaWZ0KGRmWywxXSwgMSwgdHlwZSA9ICJsYWciKSkKICAgICMgQ29tYmluZSBkYXRhCiAgICBkZl9vdXQgPSBjYmluZChkZiwgbHIpCiAgICAjIFJlbmFtZSB0aGUgZGF0YSAKICAgIGNvbG5hbWVzKGRmX291dCkgPC0gYyhzeW09c3ltYm9sLCBwYXN0ZTAoc3ltYm9sLCAiX2xvZ19yZXR1cm4iKSkKICB9IGVsc2V7CiAgICBkZl9vdXQgPSBkZgogIH0KICAjIFJldHVybiBkYXRhCiAgcmV0dXJuKGRmX291dCkKfQoKCmBgYAoKYGBge3J9CiMnIFB1bGwgdGhlIGRhdGEgYW5kIHJ1biB0aGUgQ0FWaWFSIGZ1bmN0aW9uIG9uIGl0CiMnCiMnIEBwYXJhbSBpbnB1dF9kYXRhIC0gZGF0YSB0byB1c2UgaW4gdGhlIGZ1bmN0aW9uCiMnIEBwYXJhbSByYW5nZV9kYXRhIC0gcmFuZ2Ugb2YgdGhlIGRhdGEgdG8gdXNlCiMnCiMnIEByZXR1cm4gLSBhIGxpc3Qgb2YgdmFsdWVzIGZyb20gdGhlIGNhdmlhciBmdW5jdGlvbgojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGNhdmlhcl9wdWxsKHNweSkKY2F2aWFyX3B1bGwgPSBmdW5jdGlvbihpbnB1dF9kYXRhLCByYW5nZV9kYXRhID0gKDI6ZGltKGlucHV0X2RhdGEpWzFdKSl7CiAgIyBSdW4gdGhlIGNhdmlhciBkYXRhCiAgY2F2aWFyIDwtIGNhdmlhck9wdGltKGlucHV0X2RhdGFbcmFuZ2VfZGF0YSwyXSkKICByZXR1cm4oY2F2aWFyKQp9CgpgYGAKCgpgYGB7cn0KIycgRnVuY3Rpb24gZm9yIHByb2R1Y2luZyByb2xsaW5nIHByZWRpY3Rpb25zCiMnIE1vZGVsIDEgPSBTeW1tZXRyaWMgQWJzb2x1dGUgVmFsdWUsIDIgPSBBc3ltbWV0cmljIHNsb3BlLCAzID0gSW5kaXJlY3QgR0FSQ0gsIDQgPSBBZGFwdGl2ZQojJwojJyBAcGFyYW0gaW5wdXRfZGF0YSAtIGlucHV0IGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgZnVuY3Rpb24KIycgQHBhcmFtIHJhbmdlX2RhdGEgLSByYW5nZSBvZiB0aGUgZGF0YSB0byBjb25zaWRlcgojJyBAcGFyYW0gbmZjc3QgLSBudW1iZXIgb2YgZm9yZWNhc3RzIHRvIG1ha2UKIycgQHBhcmFtIG1vZGVsIC0gbW9kZWwgdG8gdXNlIChpbnRlZ2VycyAxIHRocm91Z2ggNCkuIERlZmF1bHRzIHRvIDEuIAojJyBAcGFyYW0gbGV2ZWwgLSBsZXZlbCBvZiBzaWduaWZpY2FuY2UgdG8gdXNlLgojJyBAcGFyYW0gRyAtIGFyZ3VtZW50IGZvciB0aGUgayBwYXJhbWV0ZXIgaW4gdGhlIDR0aCBtb2RlbCAoYWRhcHRpdmUpLiBEZWZhdWx0IGlzIDUKIycKIycgQHJldHVybiAtIGFuIHh0cyBvYmplY3Qgd2hpY2ggY29udGFpbnMgcm9sbGluZyBDQVZpYVIgcHJlZGljdGlvbnMKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSByb2xsaW5nX3ByZWRpY3Rpb25zKHNweSwgbmZjc3QgPSAyMikKcm9sbGluZ19wcmVkaWN0aW9ucyA9IGZ1bmN0aW9uKGlucHV0X2RhdGEsIHJhbmdlX2RhdGEgPSAoMjpkaW0oaW5wdXRfZGF0YSlbMV0pLCBuZmNzdCA9IDI1MCwgbW9kZWwgPTEsIGxldmVsID0gMC4wMSwgRyA9IDUsIGNvbCA9IDIpewogICMgUnVuIHRoZSB2YXJwcmVkaWN0IGZ1bmN0aW9uCiAgdmFycHJlZGljdCA8LSByb2xsYXBwbHlyKGlucHV0X2RhdGFbcmFuZ2VfZGF0YSxjb2xdLCBsZW5ndGgocmFuZ2VfZGF0YSkgLSBuZmNzdCwgY2F2aWFyT3B0aW0sIG1vZGVsLCBsZXZlbCwgcHJlZGljdCA9IDEsIGsgPSBHKSAlPiUgbGFnCiAgIyBFbGltaW5hdGUgTkFzCiAgIyBwcmVkX25vX25hID0gbmEub21pdCh2YXJwcmVkaWN0KQogICMgUmV0dXJuIHRoZSBkYXRhCiAgIyByZXR1cm4ocHJlZF9ub19uYSkKICByZXR1cm4odmFycHJlZGljdCkKfQoKYGBgCgpgYGB7cn0KIycgRnVuY3Rpb24gdG8gQ2FsY3VsYXRlIExvc3MgZnJvbSB0aGUgYWJvdmUgcHJlZGljdGlvbnMKIycKIycgQHBhcmFtIHN5bWJvbCAtIHN5bWJvbCB0byB3b3JrIHdpdGggZnJvbSBxdWFudG1vZC4gTXVzdCBiZSBpbiBxdW90YXRpb25zIHRvIHdvcmsKIycgQHBhcmFtIHN0YXJ0X2R0IC0gc3RhcnQgZGF0ZSBvZiB0aGUgZGF0YSB0byBidWlsZCB0aGUgZm9yZWNhc3Qgb24gCiMnIEBwYXJhbSBlbmRfZHQgLSBlbmQgZGF0ZSBvZiB0aGUgZGF0YSB0byBidWlsZCB0aGUgZm9yZWNhc3Qgb24gIAojJyBAcGFyYW0gbmZjc3QgLSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdG8gdXNlIGluIHRoZSBmb3JlY2FzdAojJyBAcGFyYW0gbW9kZWwgLSBtb2RlbCB0byB1c2UuIERlZmF1bHRzIHRvIDEKIycgQHBhcmFtIGxldmVsIC0gbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlLiBEZWZhdWx0cyB0byAxJQojJyBAcGFyYW0gRyAtIGFyZ3VtZW50IGZvciB0aGUgayBwYXJhbWV0ZXIgaW4gdGhlIDR0aCBtb2RlbCAoYWRhcHRpdmUpLiBEZWZhdWx0IGlzIDUKIycKIycgQHJldHVybiAtIGxvc3MgdXNpbmcgYWJzb2x1dGUgdmFsdWUKIycgQGV4cG9ydCAtIGEgcGxvdCBvZiB0aGUgZGF0YQojJwojJyBAZXhhbXBsZXMKbG9zc19jYWxjX3V2ID0gZnVuY3Rpb24oc3ltYm9sLCBzdGFydF9kdCwgZW5kX2R0LCBuZmNzdCwgbW9kZWwgPSAxLCBsZXZlbCA9IDAuMDEsIEcgPSA1KXsKICAjIFB1bGwgaW4gdGhlIGRhdGEKICByYXdfZGF0YSA9IGRhdGFfcHVsbChzeW1ib2wsIHN0YXJ0X2RhdGUgPSBzdGFydF9kdCwgZW5kX2RhdGUgPSBlbmRfZHQpCiAgIyBGb3JlY2FzdCBiYXNlZCBvbiB0aGUgZGF0YQogIGZjc3QgPSBuYS5vbWl0KHJvbGxpbmdfcHJlZGljdGlvbnMocmF3X2RhdGEsIG5mY3N0ID0gbmZjc3QsIG1vZGVsID0gbW9kZWwsIGxldmVsID0gbGV2ZWwsIEcgPSBHKSkqKC0xKQogICMgRXh0cmFjdCBhY3R1YWxzCiAgYWN0ID0gdGFpbChyYXdfZGF0YSwgbiA9IG5mY3N0KVssMl0KICAjIEpvaW4gdGhlIHR3byB0b2dldGhlciBhbmQgcmVuYW1lCiAgam9pbiA9IG1lcmdlKGZjc3QsYWN0LGFsbD1UUlVFKQogIGNvbG5hbWVzKGpvaW4pIDwtIGMoIkZjc3RfVmFSIiwgIkFjdF9SZXR1cm4iKQogICMgcHJpbnQoam9pbikKICAjIENhbGN1bGF0ZSB0aGUgbG9zc2VzCiAgbG9zcyA9IGFicyhzdW0oaWZlbHNlKGFjdCA+IGZjc3QsIGxldmVsLCAoLTEpKigxLWxldmVsKSkpKQogICMgUGxvdCB0aGUgZGF0YQogIHBsb3QgPSBwbG90Lnh0cyhqb2luLCBjb2wgPSBjKCJyZWQiLCAiYmxhY2siKSwgbHR5ID0gYygyLDEpLCBtYWluID0gIkxvZyBSZXR1cm4gZnJvbSB0aGUgU1BZIHZzLiBGY3N0LiBWYVIiLGdyaWQuY29sID0gTkEsIGxlZ2VuZC5sb2MgPSAiYm90dG9tbGVmdCIpCiAgcmV0dXJuKGxpc3QobG9zcywgcGxvdCwgYWN0LCBmY3N0KSkKfQoKYGBgCgoKYGBge3IsIGNhY2hlID0gVFJVRX0KIycgVGhpcyBpcyBhIGZ1bmN0aW9uIHdoaWNoIGNyZWF0ZXMgYSBkYXRhIGZyYW1lIGZvciB0aGUgcmVzcG9uc2UgYW5kIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyB0aGF0IHdlJ2xsIGZlZWQgaW50byB0aGUgZGlmZnVzaW9uIGluZGV4CiMnCiMnIEBwYXJhbSBzeW1ib2xfbGlzdCAtIGEgbGlzdCBvZiBzeW1ib2xzIHJlY29nbml6YWJsZSBieSB0aGUgCiMnIEBwYXJhbSByZXNwX3ZhciAtIHRoZSByZXNwb25zZSB2YXJpYWJsZSB3ZSdkIGxpa2UgdG8gZm9yZWNhc3Q7IGRlZmF1bHQgaXMgU1BZCiMnIEBwYXJhbSBjb21wbF9jYXNlIC0gZGVmYXVsdHMgdG8gdHJ1ZS4uLm9ubHkgaW5jbHVkZXMgY29tcGxldGUgY2FzZXMgaW4gdGhlIGRhdGEKIycgQHBhcmFtIGFkal9jbG9zZSAtIHVzZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBmb3IgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcz8gZGVmYXVsdCBpcyAxIGZvciBZRVMKIycgQHBhcmFtIHJlc3BfYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzIGZvciB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzPyBkZWZhdWx0IGlzIDEgZm9yIFlFUwojJyBAcGFyYW0gc3RhcnRfZGF0ZSAtIHN0YXJ0aW5nIGRhdGEgdG8gdXNlCiMnIEBwYXJhbSBlbmRfZGF0ZSAtIGVuZGluZyBkYXRlIG9mIHRoZSBkYXRhCiMnIEBwYXJhbSBsYWdfcHJlZCAtIGRvIHdlIGxhZyB0aGUgcHJlZGljdGlvbnM/IEl0IGlzIFNUUk9OR0xZIHJlY29tbWVuZGVkIHRoYXQgdGhpcyBpcyAwCiMnCiMnIEByZXR1cm4gLSBhIGRhdGEgZnJhbWUgd2hpY2ggY2FuIGJlIGZlZCBpbnRvIHRoZSBTV2ZvcmUgZnVuY3Rpb24KIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBkaWZmX2luZGV4X2RmKGMoIlhMRiIsICJYTEUiLCAiUFNDVCIsICJYTFYiLCAiVlBVIiwgIlhMUCIsICJJR0YiLCAiWFdFQiIsICJQUFRZIikpCmRpZmZfaW5kZXhfZGYgPSBmdW5jdGlvbihzeW1ib2xfbGlzdCwgcmVzcF92YXIgPSAiU1BZIiwgY29tcGxfY2FzZSA9IDEsIGFkal9jbG9zZSA9IDEsIHJlc3BfYWRqX2Nsb3NlID0gMSwgc3RhcnRfZGF0ZSA9ICIxOTAwLTAxLTAxIiwgZW5kX2RhdGUgPSBTeXMuRGF0ZSgpLCBsYWdfcHJlZCA9IDEpewogICMgUHVsbCBpbiByZXNwb25zZSB2YXJpYWJsZQogIHJlc3BvbnNlX3B1bGwgPSBnZXRTeW1ib2xzKHJlc3BfdmFyLCBhdXRvLmFzc2lnbiA9IEZBTFNFLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKICAjIEdldCBhZGp1c3RlZCBjbG9zaW5nIHByaWNlCiAgaWYgKHJlc3BfYWRqX2Nsb3NlID09IFRSVUUpewogICAgZGlmZl9kZiA9IEFkKHJlc3BvbnNlX3B1bGwpCiAgfSBlbHNlIHsKICAgIGRpZmZfZGYgPSBDbChyZXNwb25zZV9wdWxsKQogIH0KICAjIExvb3AgdGhyb3VnaCB0aGUgc3ltYm9scyBhbmQgam9pbiBpbiBkYXRhCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN5bWJvbF9saXN0KSl7CiAgICAjIFB1bGwgY2xvc2luZyBwcmljZQogICAgZXhwbF9wdWxsID0gZ2V0U3ltYm9scyhzeW1ib2xfbGlzdFtpXSwgYXV0by5hc3NpZ24gPSBGQUxTRSwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpCiAgICAjIEV4dHJhY3QgY2xvc2luZyBwcmljZSAtIDR0aCBlbGVtZW50CiAgICBpZiAoYWRqX2Nsb3NlID09IFRSVUUpewogICAgICBleHBsX2NsID0gQWQoZXhwbF9wdWxsKQogICAgfSBlbHNlIHsKICAgICAgZXhwbF9jbCA9IENsKGV4cGxfcHVsbCkKICAgIH0KICAgICMgTmV3IGNvZGUgZm9yIDQuMTYuMjAyMCAtIGxhZyB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzCiAgICBpZiAobGFnX3ByZWQgPT0gVFJVRSl7CiAgICAgICMgTGFnIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYnkgMQogICAgICBsYWdfZXhwID0gbGFnKGV4cGxfY2wsIDEpCiAgICAgICMgQXBwZW5kIHRoZSBmaXJzdCBsYWcgdG8gdGhlIGRhdGEgZnJhbWUKICAgICAgZGlmZl9kZiA9IG1lcmdlKGRpZmZfZGYsIGxhZ19leHAsIGpvaW4gPSAibGVmdCIsIGZpbGwgPSBOQSkKICAgIH0gZWxzZXsKICAgICAgIyBSZXR1cm4gdGhlIGRhdGEgZnJhbWUgd2l0aG91dCBsYWdzCiAgICAgIGRpZmZfZGYgPSBtZXJnZShkaWZmX2RmLCBleHBsX2NsLCBqb2luID0gImxlZnQiLCBmaWxsID0gTkEpCiAgICB9CiAgfQogIGlmIChsYWdfcHJlZCA9PSBUUlVFKXsKICAgICMgQ2hvcCBvZmYgdGhlIGZpcnN0IHJvdwogICAgZGlmZl9kZiA9IGRpZmZfZGZbLTEsXQogIH0KICBlbHNlIHsKICAgIHByaW50KCJQTEVBU0UgTk9URSAtIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgaW4gdGhpcyBERiBhcmUgTk9UIGxhZ2dlZC4gQmUgY2FyZWZ1bCB0byBhdm9pZCBsb29rLWFoZWFkIGJpYXMhIikKICB9CiAgIyBSZXR1cm4gY29tcGxldGUgY2FzZXMgb25seSAKICBpZiAoY29tcGxfY2FzZSA9PSBUUlVFKXsKICAgIGRpZmZfZGZfb3V0ID0gZGlmZl9kZltjb21wbGV0ZS5jYXNlcyhkaWZmX2RmKSwgXQogIH0gZWxzZXsKICAgIGRpZmZfZGZfb3V0ID0gZGlmZl9kZgogIH0KICAKICByZXR1cm4oZGlmZl9kZl9vdXQpCn0KCmBgYAoKYGBge3IsIGNhY2hlID0gVFJVRX0KIycgQ29udmVydHMgYSBkaWZmX2RmIGludG8gYSBkYXRhIGZyYW1lIHdpdGggYXBwcm94aW1hdGUgcGVyY2VudGFnZSBjaGFuZ2VzIGRpZmYobG9nKGRpZmZfZGYpKQojJwojJyBAcGFyYW0gZGlmZl9kZiAtIG91dHB1dCBvZiB0aGUgZGlmZl9pbmRleF9kZiBmdW5jdGlvbiB3aXRoIGNvbXBsZXRlIGNhc2VzCiMnCiMnIEByZXR1cm4gLSByZXR1bnMgdGhlIGRpZmZlcmVuY2VkIGRhdGEKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBwY19kaWZmX2luZGV4KHRlc3RfY29tcGwpIAoKcGNfZGlmZl9pbmRleCA9IGZ1bmN0aW9uKGRpZmZfZGYpewogICMgRGlmZmVyZW5jZSB0aGUgbG9nIG9mIHRoZSBkYXRhCiAgcGNfZGlmZl9pbmRleCA9IGRpZmYobG9nKGRpZmZfZGYpKQogICMgUmVtb3ZlIHRoZSBmaXJzdCByb3cKICBwY19kaWZmX2luZGV4X291dCA9IHBjX2RpZmZfaW5kZXhbLTEsXQogIHJldHVybihwY19kaWZmX2luZGV4X291dCkKfQoKYGBgCgoKYGBge3J9CiMnIEJlbG93IGlzIHRoZSBtb2RpZmllZCBkaWZmdXNpb24gaW5kZXggY29kZS4KIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2YXJpYWJsZQojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIG0gLSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGV4ZXMgdXNlZAojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsIHRvIHVzZTsgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEKIycgQHBhcmFtIGVuZCAtIHNwZWNpZmllcyBhbiBhbHRlcm5hdGUgZW5kaW5nIHZhbHVlCiMnIEBwYXJhbSBwcmludF9tZGwgLSBwcmludCB0aGUgbW9kZWwgc3VtbWFyeSBhbmQgdGhlIE1TRQojJwojJyBAcmV0dXJuIC0gcmV0dXJucyBhIGxpc3Qgb2YgdmFyaWFibGVzIGZvciB1c2UgaW4gdGhlIGRpZmZ1c2lvbiBpbmRleAojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcwptb2RfZGkgPSBmdW5jdGlvbiAoeSwgeCwgb3JpZywgbSwgdGF1LCBlbmQgPSBOVUxMLCBwcmludF9tZGwgPSAwKSAKewogICMgQ29udmVydHMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlcyBpbnRvIGEgbWF0cml4CiAgaWYgKCFpcy5tYXRyaXgoeCkpIAogICAgICB4ID0gYXMubWF0cml4KHgpCiAgIyBuVCBpcyBudW1iZXIgb2YgdCB0aW1lLXN0ZXBzCiAgblQgPSBkaW0oeClbMV0KICAjIEFkZCBhIGxpbmUgdG8gZXN0YWJsaXNoIHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdXNlZCBpbiB0aGUgdGVzdC4KICBpZiAoaXMubnVsbChlbmQpICE9IFRSVUUpewogICAgblQgPSBlbmQKICB9CiAgIyBrIGlzIHRoZSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGljZXMgdXNlZAogIGsgPSBkaW0oeClbMl0KICAjIFNhbml0eSBjaGVja3MgdG8gZW5zdXJlIHRoYXQgdGhlIG9yaWdpbiBpc24ndCBwYXN0IHRoZSBudW1iZXIgb2YgdGltZSBwb2ludHMKICBpZiAob3JpZyA+IG5UKSAKICAgICAgb3JpZyA9IG5UCiAgIyBNYWtlcyBzdXJlIHRoYXQgdGhlcmUgYXJlbid0IG1vcmUgcHJlZGljdG9ycyB0aGFuIHRoZXJlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldAogIGlmIChtID4gaykgCiAgICAgIG0gPSBrCiAgIyBNYWtlcyBzdXJlIHRoZXJlIGFyZSBhdCBsZWFzdCBzb21lIHZhcmlhYmxlcwogIGlmIChtIDwgMSkgCiAgICAgIG0gPSAxCiAgIyBTdWJkaXZpZGVzIHRoZSBkYXRhZnJhbWUKICB4MSA9IHhbMTpvcmlnLCBdCiAgIyBDYWxjdWxhdGVzIG1lYW5zIG9mIGVhY2ggcm93CiAgbWUgPSBhcHBseSh4MSwgMiwgbWVhbikKICAjIENhbGN1bGF0ZXMgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiBlYWNoIGNvbHVtbgogIHNlID0gc3FydChhcHBseSh4MSwgMiwgdmFyKSkKICAjIENyZWF0ZXMgYSBtYXRyaXggeDEsIHdoaWNoIG5vcm1hbGl6ZXMgYWxsIHRoZSBjb2x1bW5zLiAKICAjIFRoaXMgbWF5IGJlIGFuIGlzc3VlIHNpbmNlIGl0IGFzc3VtZXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIGlzIHN1ZmZpY2llbnRseSBkZXNjcmliZWQgYnkgdGhlIGZpcnN0IHR3byBtb21lbnRzCiAgeDEgPSB4CiAgZm9yIChpIGluIDE6aykgewogICAgICB4MVssIGldID0gKHgxWywgaV0gLSBtZVtpXSkvc2VbaV0KICB9CiAgVjEgPSBjb3YoeDFbMTpvcmlnLCBdKQogICMgUGVyZm9ybXMgYW4gZWlnZW4gZGVjb21wb3NpdGlvbgogIG0xID0gZWlnZW4oVjEpCiAgIyBTZWxlY3RzIGVpZ2VudmFsdWVzCiAgc2RldiA9IG0xJHZhbHVlcwogICMgU2VsZWN0cyBlaWdlbnZlY3RvcnMKICBNID0gbTEkdmVjdG9ycwogICMgTWFrZXMgYSBzbWFsbGVyIG1hdHJpeAogIE0xID0gTVssIDE6bV0KICAjIFRoaXMgaXMgdGhlIGRpZmZ1c2lvbiBpbmRleCBtb2RlbCAtIFtvcmlnIHggcF0qW3AgeCBtXSA9IFtvcmlnIHggbV0KICBEaW5kZXggPSB4MSAlKiUgTTEKICAjIEN1dCBkb3duIGJvdGggdGhlIHJlc3BvbnNlIGFuZCBwcmVkaWN0b3JzIHRvIGJlIGEgcmVhc29uYWJsZSBzaXplCiAgeTEgPSB5WzE6b3JpZ10KICBERiA9IERpbmRleFsxOm9yaWcsIF0KICAjIEFwcGx5IHRoZSBsaW5lYXIgbW9kZWwgLSBIRVJFIGlzIHRoZSBrZXkuCiAgIyBtbSA9IGxtKHkxIH4gREYpIC0gb2xkIGZ1bmN0aW9uCiAgbW0gPSBycSh5MSB+IERGLCB0YXUgPSB0YXUpCiAgIyBQcmludCB0aGUgZGF0YQogIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICBwcmludChzdW1tYXJ5KG1tKSkKICB9CiAgIyBQdXRzIGNvZWZmaWNpZW50cyBpbiBhIG1hdHJpeAogIGNvZWYgPSBtYXRyaXgobW0kY29lZmZpY2llbnRzLCAobSArIDEpLCAxKQogICMgSW5pdGlhbGl6ZXMgeWhhdCB2YXJpYWJsZXMgYW5kIE1TRQogIHloYXQgPSBOVUxMCiAgTVNFID0gTlVMTAogIGlmIChvcmlnIDwgblQpIHsKICAgICMgQ3JlYXRlcyBhIG5mY3N0IGJ5IChtKzEpIG1hdHJpeAogICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCAKICAgICAgICBdKQogICAgIyBbbmZjc3R4KG0rMSldKlsobSsxKXgxXSA9IFtuZmNzdHgxXQogICAgeWhhdCA9IG5ld3ggJSolIGNvZWYKICAgICMgQ2FsY3VsYXRlcyBlcnJvcnMKICAgIGVyciA9IHlbKG9yaWcgKyAxKTpuVF0gLSB5aGF0CiAgICBNU0UgPSBtZWFuKGVycl4yKQogICAgaWYgKHByaW50X21kbCA9PSAxKXsKICAgICAgY2F0KCJNU0Ugb2Ygb3V0LW9mLXNhbXBsZSBmb3JlY2FzdHM6ICIsIE1TRSwgIlxuIikKICAgIH0KICB9CiAgU1dmb3JlIDwtIGxpc3QoY29lZiA9IGNvZWYsIHloYXQgPSB5aGF0LCBNU0UgPSBNU0UsIGxvYWRpbmdzID0gTTEsIAogICAgICBERmluZGV4ID0gRGluZGV4KQp9CgpgYGAKCgpgYGB7cn0KIycgQmVsb3cgaXMgdGhlIG1vZGlmaWVkIGRpZmZ1c2lvbiBpbmRleCBjb2RlIHRvIGluY2x1ZGUgbGFnZ2VkIHZhcmlhYmxlcy4KIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2YXJpYWJsZQojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIG0gLSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGV4ZXMgdXNlZAojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsIHRvIHVzZTsgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEKIycgQHBhcmFtIGFyX3RmIC0gQVIgdHJhbnNmb3JtYXRpb24gdHlwZS4gKDEgLSBubyB0cmFuc2Zvcm1hdGlvbiwKIycgMiAtIGFic29sdXRlIHZhbHVlLCAzIC0gYXN5bW1ldHJpYyBzbG9wZSkKIycgQHBhcmFtIHAgLSBudW1iZXIgb2YgQVIgbGFncyB0byBpbmNsdWRlLiBEZWZhdWx0IGlzIG9uZS4KIycgQHBhcmFtIHByaW50X21kbCAtIG9wdGlvbiB0byBwcmludCB0aGUgbW9kZWwgc3VtbWFyeSB0byBtYWtlIHN1cmUgZXZlcnl0bmluZyBpcyBvay4gMCBpcyBkZWZhdWx0LgojJyBAcGFyYW0gbW9kZWwgLSBtb2RlbCB0eXBlICgxIC0gU0FWLCAyIC0gQVMsIDMgLSBHQVJDSCwgNCAtIEFEQVBUSVZFKSAKIycKIycgQHJldHVybiAtIHJldHVybnMgYSBsaXN0IG9mIHZhcmlhYmxlcyBmb3IgdXNlIGluIHRoZSBkaWZmdXNpb24gaW5kZXgKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKbW9kX2RpX3dsID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxLCBlbmQgPSBOVUxMKSAKewogICMgQ29udmVydHMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlcyBpbnRvIGEgbWF0cml4CiAgaWYgKCFpcy5tYXRyaXgoeCkpIAogICAgICB4ID0gYXMubWF0cml4KHgpCiAgIyBuVCBpcyBudW1iZXIgb2YgdCB0aW1lLXN0ZXBzCiAgblQgPSBkaW0oeClbMV0KICAjIEFkZCBhIGxpbmUgdG8gZXN0YWJsaXNoIHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdXNlZCBpbiB0aGUgdGVzdC4KICBpZiAoaXMubnVsbChlbmQpICE9IFRSVUUpewogICAgblQgPSBlbmQKICB9CiAgIyBrIGlzIHRoZSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGljZXMgdXNlZAogIGsgPSBkaW0oeClbMl0KICAjIFNhbml0eSBjaGVja3MgdG8gZW5zdXJlIHRoYXQgdGhlIG9yaWdpbiBpc24ndCBwYXN0IHRoZSBudW1iZXIgb2YgdGltZSBwb2ludHMKICBpZiAob3JpZyA+IG5UKSAKICAgICAgb3JpZyA9IG5UCiAgIyBNYWtlcyBzdXJlIHRoYXQgdGhlcmUgYXJlbid0IG1vcmUgcHJlZGljdG9ycyB0aGFuIHRoZXJlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldAogIGlmIChtID4gaykgCiAgICAgIG0gPSBrCiAgIyBNYWtlcyBzdXJlIHRoZXJlIGFyZSBhdCBsZWFzdCBzb21lIHZhcmlhYmxlcwogIGlmIChtIDwgMSkgCiAgICAgIG0gPSAxCiAgIyBTdWJkaXZpZGVzIHRoZSBkYXRhZnJhbWUKICB4MSA9IHhbMTpvcmlnLCBdCiAgIyBDYWxjdWxhdGVzIG1lYW5zIG9mIGVhY2ggcm93CiAgbWUgPSBhcHBseSh4MSwgMiwgbWVhbikKICAjIENhbGN1bGF0ZXMgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiBlYWNoIGNvbHVtbgogIHNlID0gc3FydChhcHBseSh4MSwgMiwgdmFyKSkKICAjIENyZWF0ZXMgYSBtYXRyaXggeDEsIHdoaWNoIG5vcm1hbGl6ZXMgYWxsIHRoZSBjb2x1bW5zLiAKICAjIFRoaXMgbWF5IGJlIGFuIGlzc3VlIHNpbmNlIGl0IGFzc3VtZXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIGlzIHN1ZmZpY2llbnRseSBkZXNjcmliZWQgYnkgdGhlIGZpcnN0IHR3byBtb21lbnRzCiAgeDEgPSB4CiAgZm9yIChpIGluIDE6aykgewogICAgICB4MVssIGldID0gKHgxWywgaV0gLSBtZVtpXSkvc2VbaV0KICB9CiAgVjEgPSBjb3YoeDFbMTpvcmlnLCBdKQogICMgUGVyZm9ybXMgYW4gZWlnZW4gZGVjb21wb3NpdGlvbgogIG0xID0gZWlnZW4oVjEpCiAgIyBTZWxlY3RzIGVpZ2VudmFsdWVzCiAgc2RldiA9IG0xJHZhbHVlcwogICMgU2VsZWN0cyBlaWdlbnZlY3RvcnMKICBNID0gbTEkdmVjdG9ycwogICMgTWFrZXMgYSBzbWFsbGVyIG1hdHJpeAogIE0xID0gTVssIDE6bV0KICAjIFRoaXMgaXMgdGhlIGRpZmZ1c2lvbiBpbmRleCBtb2RlbCAtIFtvcmlnIHggcF0qW3AgeCBtXSA9IFtvcmlnIHggbV0KICBEaW5kZXggPSB4MSAlKiUgTTEKICAjIEN1dCBkb3duIGJvdGggdGhlIHJlc3BvbnNlIGFuZCBwcmVkaWN0b3JzIHRvIGJlIGEgcmVhc29uYWJsZSBzaXplCiAgeTEgPSB5WzE6b3JpZ10KICBERiA9IERpbmRleFsxOm9yaWcsIF0KICAjIENvcHkgdGhlIGRhdGEgZnJhbWUKICBERl93bCA9IERpbmRleAogICMgTGFnIHRoZSB5LXZhcmlhYmxlCiAgZm9yIChpIGluIDE6cCl7CiAgICAjIENyZWF0ZSBhIGxhZ2dlZCB2YXJpYWJsZQogICAgbGFnX3ZhciA9IGxhZyh5LCBpKQogICAgIyBBcHBlbmQgdGhlIGZpcnN0IGxhZyB0byB0aGUgZGF0YSBmcmFtZQogICAgREZfd2wgPSBjYmluZChERl93bCxsYWdfdmFyKQogIH0KICAjIElkZW50aWZ5IHRoZSByaWdodCBjb2x1bW5zCiAgbF9hciA9IG5jb2woREZfd2wpCiAgZl9hciA9IGxfYXIgLSBwICsgMQogICMgS2VlcCB0aGUgbGFzdCBjb2x1bW5zIGtlcHQgdG8gdGhlIHNpZGUKICBhbGxfbGFnID0gREZfd2xbLChmX2FyOmxfYXIpXQogICMgQ3V0IG9mZiB0aGUgZmlyc3Qgcm93IHRvIGF2b2lkIE5BJ3MKICBERl90cmltID0gREZfd2xbMTpvcmlnLF0KICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICMgSGVyZSdzIHRoZSBuZXcgZnVuY3Rpb24gd2l0aCBhbiB1bnRyYW5zZm9ybWVkIEFSKHApIGxhZwogIGlmIChhcl90ZiA9PSAxKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLF0pCiAgICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICAgIyBJbml0aWFsaXplIGEgY2hhcmFjdGVyIHZlY3RvcgogICAgbnZlYyA9IGMocmVwKDAsIDErbStwKSkKICAgICMgUG9wdWxhdGUgdGhlIHZlY3RvciAtIGZpcnN0IHZhbHVlIGlzIHRoZSByZXNwb25zZQogICAgbnZlY1sxXSA8LSBuYW1lcyh5KQogICAgIyBOZXh0IGFyZSB0aGUgZGlmZnVzaW9uIGluZGljZXMKICAgIGZvciAoaSBpbiAxOm0pewogICAgICBudmVjW2krMV0gPSBwYXN0ZTAoIkRpZmZfSW5kZXhfIiwgaSkKICAgIH0KICAgICMgTmV4dCBhcmUgdGhlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIGZvciAoaSBpbiAxOnApewogICAgICBudmVjW2krMSttXSA9IHBhc3RlMCgiTGFnXyIsIGkpCiAgICB9CiAgICAjIEFzc2lnbiB0aGUgbmFtZXMKICAgIG5hbWVzKGRmX2luKSA8LSBudmVjCiAgICAjIFJ1biB0aGUgbW9kZWwKICAgIG1tID0gcnEoZGZfaW5bLDFdIH4gZGZfaW5bLC0xXSwgdGF1ID0gdGF1KQogIH0KICAjIEhlcmUncyB0aGUgbmV3IGZ1bmN0aW9uIHdpdGggYW4gU0FWIEFSKHApIGxhZwogIGlmIChhcl90ZiA9PSAyKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLC0oZl9hcjpsX2FyKV0sIGFicyhERl90cmltWy0oMTpwKSwoZl9hcjpsX2FyKV0pKQogICAgIyBSZW5hbWUgdGhlIGNvbHVtbnMKICAgICMgSW5pdGlhbGl6ZSBhIGNoYXJhY3RlciB2ZWN0b3IKICAgIG52ZWMgPSBjKHJlcCgwLCAxK20rcCkpCiAgICAjIFBvcHVsYXRlIHRoZSB2ZWN0b3IgLSBmaXJzdCB2YWx1ZSBpcyB0aGUgcmVzcG9uc2UKICAgIG52ZWNbMV0gPC0gbmFtZXMoeSkKICAgICMgTmV4dCBhcmUgdGhlIGRpZmZ1c2lvbiBpbmRpY2VzCiAgICBmb3IgKGkgaW4gMTptKXsKICAgICAgbnZlY1tpKzFdID0gcGFzdGUwKCJEaWZmX0luZGV4XyIsIGkpCiAgICB9CiAgICAjIE5leHQgYXJlIHRoZSBsYWdnZWQgdmFyaWFibGVzCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgbnZlY1tpKzErbV0gPSBwYXN0ZTAoIkxhZ18iLCBpKQogICAgfQogICAgIyBBc3NpZ24gdGhlIG5hbWVzLiBOb3RlIHRoYXQgdGhpcyBpcyBhIG1hdHJpeAogICAgbmFtZXMoZGZfaW4pIDwtIG52ZWMKICAgICMgUnVuIHRoZSBtb2RlbAogICAgbW0gPSBycShkZl9pblssMV0gfiBkZl9pblssLTFdLCB0YXUgPSB0YXUpCiAgfQogICMgSGVyZSdzIHRoZSBuZXcgZnVuY3Rpb24gd2l0aCBhbiBhc3ltbWV0cmljIHNsb3BlIGZvciB0aGUgQVIoMSkgbGFnCiAgIyBJbmRpY2F0b3I7IDAgaWYgcGVyY2VudCBjaGFuZ2UgaXMgbmVnYXRpdmUsIDEgaWYgaXQncyBwb3NpdGl2ZQogICMgaW5kaSA9IGlmZWxzZShERl90cmltWyxhcl0gPCAwLCAwLCAxKQogIGlmIChhcl90ZiA9PSAzKXsKICAgICMgQ3JlYXRlIGEgbWF0cml4IG9mIGluZGljYXRvcnMKICAgIGluZGlfbWF0ID0gbWF0cml4KDAsIG5yb3coREZfd2wpLCBwKQogICAgIyBHZW5lcmFsaXplIHRoZSBhYm92ZSBjb2RlCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgIyBQb3B1bGF0ZSB0aGUgaW5kaWNhdG9yCiAgICAgIGluZGlfbWF0WyxpXSA9IGlmZWxzZShERl93bFssZl9hciArIGkgLSAxXSA8IDAsIDAsIDEpCiAgICB9CiAgfQogICMgRml0dGluZyB0aGUgcmVncmVzc2lvbgogIGlmIChhcl90ZiA9PSAzKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLC0oZl9hcjpsX2FyKV0sIERGX3RyaW1bLSgxOnApLChmX2FyOmxfYXIpXSwgaW5kaV9tYXRbKChwKzEpOm9yaWcpLF0pCiAgICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICAgIyBJbml0aWFsaXplIGEgY2hhcmFjdGVyIHZlY3RvcgogICAgbnZlYyA9IGMocmVwKDAsIDErbSsyKnApKQogICAgIyBQb3B1bGF0ZSB0aGUgdmVjdG9yIC0gZmlyc3QgdmFsdWUgaXMgdGhlIHJlc3BvbnNlCiAgICBudmVjWzFdIDwtIG5hbWVzKHkpCiAgICAjIE5leHQgYXJlIHRoZSBkaWZmdXNpb24gaW5kaWNlcwogICAgZm9yIChpIGluIDE6bSl7CiAgICAgIG52ZWNbaSsxXSA9IHBhc3RlMCgiRGlmZl9JbmRleF8iLCBpKQogICAgfQogICAgIyBOZXh0IGFyZSB0aGUgbGFnZ2VkIHZhcmlhYmxlcwogICAgZm9yIChpIGluIDE6cCl7CiAgICAgIG52ZWNbaSsxK21dID0gcGFzdGUwKCJMYWdfIiwgaSkKICAgIH0KICAgICMgTGFzdCBhcmUgdGhlIHBvc2l0aXZlIGluZGljYXRvciB2YXJpYWJsZXMKICAgIGZvciAoaSBpbiAxOnApewogICAgICBudmVjW2krMSttK3BdID0gcGFzdGUwKCJQb3NfVmFsX2Zvcl9MYWdfIiwgaSkKICAgIH0KICAgICMgQXNzaWduIHRoZSBuYW1lcy4gTm90ZSB0aGF0IHRoaXMgaXMgYSBtYXRyaXgKICAgIG5hbWVzKGRmX2luKSA8LSBudmVjCiAgICAjIFJ1biB0aGUgbW9kZWwKICAgIG1tID0gcnEoZGZfaW5bLDFdIH4gZGZfaW5bLC0xXSwgdGF1ID0gdGF1KQogICAgIyBtbSA9IHJxKHkxWy0oMTpwKV0gfiBERl90cmltWy0oMTpwKSwtKGZfYXI6bF9hcildICsgREZfdHJpbVstKDE6cCksKGZfYXI6bF9hcildICsgaW5kaV9tYXRbKChwKzEpOm9yaWcpLF0sIHRhdSA9IHRhdSkKICAgICMgQWRkIGEgZGlmZmVyZW50IGxpbmUgdG8gYWNjb3VudCBmb3IgdGhlIGluZGljYXRvciB2YXJpYWJsZQogICAgIyBpbnRlcmNlcHQgKyBtICsgMipubGFnIHRvIGFjY291bnQgZm9yIHRoZSBudW1iZXIgb2YgaW5kaWNhdG9yIHZhcmlhYmxlcwogICAgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsICgxICsgbSArIDIqcCksIDEpCiAgfQogIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICBwcmludChzdW1tYXJ5KG1tKSkKICB9CiAgIyBQdXRzIGNvZWZmaWNpZW50cyBpbiBhIG1hdHJpeCAtIGFkZGVkIHRoZSBBUiB0ZXJtcwogICMgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsIChtICsgMSksIDEpCiAgaWYgKGFyX3RmICE9IDMpewogICAgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsICgxICsgbSArIHApLCAxKQogIH0KICAjIEluaXRpYWxpemVzIHloYXQgdmFyaWFibGVzIGFuZCBNU0UKICB5aGF0ID0gTlVMTAogIGxvc3MgPSBOVUxMCiAgaWYgKG9yaWcgPCBuVCkgewogICAgIyBDcmVhdGVzIGEgbmZjc3QgYnkgKG0rMikgbWF0cml4CiAgICAjIEFkZCBvbiB0aGUgbGFnZ2VkIHZhcmlhYmxlcwogICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCBdLCBhbGxfbGFnWyhvcmlnKzEpOm5ULF0pCiAgICAjIEluY29ycG9yYXRlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIGlmIChhcl90ZiA9PSAzKXsKICAgICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCBdLCBhbGxfbGFnWyhvcmlnKzEpOm5ULF0sIGluZGlfbWF0WyhvcmlnKzEpOm5ULF0pCiAgICB9CiAgICAjIFtuZmNzdHgobSsxKV0qWyhtKzEpeDFdID0gW25mY3N0eDFdCiAgICB5aGF0ID0gbmV3eCAlKiUgY29lZgogICAgIyBDYWxjdWxhdGVzIGVycm9ycwogICAgbG9zcyA9IGFicyhzdW0oaWZlbHNlKHlbKG9yaWcgKyAxKTpuVF0gPiB5aGF0LCB0YXUsICgtMSkqKDEtdGF1KSkpKQogICAgIyBNb2RpZnlpbmcgdGhpcyBwYXJ0IHRvIG9ubHkgcHJpbnQgdGhpcyBpZiBzcGVjaWZpZWQKICAgIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICAgIGNhdCgiTG9zc2VzIG9mIG91dC1vZi1zYW1wbGUgZm9yZWNhc3RzOiAiLCBsb3NzLCAiXG4iKQogICAgfQogIH0KICBTV2ZvcmUgPC0gbGlzdChjb2VmID0gY29lZiwgeWhhdCA9IHloYXQsIGxvc3MgPSBsb3NzLCBsb2FkaW5ncyA9IE0xLCAKICAgICAgREZpbmRleCA9IERpbmRleCwgbmFtZV92ZWN0b3IgPSBudmVjKQp9CgpgYGAKCmBgYHtyfQojIERlY2lkZSBvbiB0aGUgb3B0aW1hbCBudW1iZXIgb2YgdmVjdG9ycy4KCiMgKHksIHgsIG9yaWcsIG0sIHRhdSkgCgojJyBGdW5jdGlvbiB0aGF0IGNhbGN1bGF0ZXMgbG9zcyBvdmVyIGEgZ2l2ZW4gcGVyaW9kIG9mIHRpbWUgZm9yIHRoZSBkaWZmdXNpb24gaW5kZXggbW9kZWwKIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2YXJpYWJsZXMKIycgQHBhcmFtIHggLSBleHBsYW5hdG9yeSB2YXJpYWJsZQojJyBAcGFyYW0gb3JpZyAtIGZvcmVjYXN0IG9yaWdpbgojJyBAcGFyYW0gZW5kIC0gZm9yZWNhc3RpbmcgZW5kaW5nLiBOb3RlOiBhcyB0aGUgZnVuY3Rpb24gaXMgY3VycmVudGx5IHdyaXR0ZW4gb24gMi8yNCwgdGhpcyBvcHRpb24gZG9lc24ndCBkbyBhbnl0aGluZy4KIycgQHBhcmFtIG0gLSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGljZXMgdG8gdXNlCiMnIEBwYXJhbSB0YXUgLSBWYVIgbGV2ZWwKIycgQHBhcmFtIG1vZF9kaSAtIHVzZSB0aGUgbW9kaWZpZWQgREk/CiMnCiMnIEByZXR1cm4gLSByZXR1cm5zIGEgbGlzdCBvZiB0aGUgbG9zcyBzdW0gYW5kIHRoZSBsb3NzIHZlY3RvcgojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGxvc3NfY2FsYyhwY19kZlssMV0sIHBjX2RmWywtMV0sIDc1NywgMTAyNywgMSwgMC4wMSkKbG9zc19jYWxjID0gZnVuY3Rpb24oeSwgeCwgb3JpZywgbSwgdGF1LCBtb2RfZGkgPSAwLCBhcl90ZiA9IDEsIHAgPSAxLCBwcmludF9tZGwgPSAwLCBtb2RlbCA9IDEsIGVuZCA9IE5VTEwpewogICMgRXh0cmFjdCB5X2hhdCB2YWx1ZXMKICBpZiAobW9kX2RpID09IDApewogICAgZGkgPSBtb2RfZGkoeT15LHg9eCxvcmlnPW9yaWcsbT1tLCB0YXU9dGF1LCBlbmQgPSBlbmQsIHByaW50X21kbCA9IHByaW50X21kbCkKICB9CiAgZWxzZSB7CiAgICBkaSA9IG1vZF9kaV93bCh5PXkseD14LG9yaWc9b3JpZyxtPW0sIHRhdT10YXUsIGFyX3RmID0gYXJfdGYsIHAgPSBwLCBwcmludF9tZGwgPSBwcmludF9tZGwsIG1vZGVsID0gbW9kZWwsIGVuZCA9IGVuZCkKICB9CiAgIyBtb2RfZGlfd2wgPSBmdW5jdGlvbiAoeSwgeCwgb3JpZywgbSwgdGF1LCBhcl90ZiA9IDEsIHAgPSAxLCBwcmludF9tZGwgPSAwLCBtb2RlbCA9IDEpCiAgeWhhdCA9IGRpJHloYXRbMTooZW5kLW9yaWcpXQogICMgQ2FsY3VsYXRlIHRoZSBsb3NzCiAgIyBJbml0aWFsaXplIGxvc3MgdmVjdG9yCiAgbHZlYyA9IHJlcCgwLChlbmQtb3JpZykpCiAgIyBUYWtlIHRoZSBkaWZmZXJlbmNlCiAgZm9yIChpIGluIDE6KGVuZC1vcmlnKSl7CiAgICAjIENhbGN1bGF0ZSBhbiBpbmRpY2F0b3IgdmFyaWFibGUKICAgIGluZCA9IGlmZWxzZSh5W29yaWcraV0gPCB5aGF0W2ldLCAxLDApCiAgICAjIFVzZSBpbmRpY2F0b3IgaW4gZnVuY3Rpb24gYmVsb3cKICAgIGx2ZWNbaV0gPSAodGF1IC0gaW5kKSooeVtvcmlnK2ldIC0geWhhdFtpXSkKICB9CiAgIyBBZGQgdXAgdGhlIGxvc3NlcyAtIGNoYW5nZSB0byBsb29rIGF0IHN1bSBvZiBsb3NzZXMuIFdvbid0IGNoYW5nZSBkZWNpc2lvbiBjcml0ZXJpb24KICBzdW1sb3NzID0gc3VtKGx2ZWMpCiAgIyBzdW1sb3NzID0gc3VtKGx2ZWMpL2xlbmd0aChsdmVjKQogIHJldHVybihsaXN0KHN1bWxvc3MsbHZlYykpCn0KCgpgYGAKCgpgYGB7cn0KIycgRnVuY3Rpb24gdGhhdCBzZWxlY3RzIHRoZSBvcHRpbWFsIG51bWJlciBvZiBwcmVkaWN0b3JzCiMnCiMnIEBwYXJhbSB5IC0gcmVzcG9uc2UgdmVjdG9yCiMnIEBwYXJhbSB4IC0gcHJlZGljdG9yIHZhcmlhYmxlcwojJyBAcGFyYW0gb3JpZyAtIGZvcmVjYXN0IG9yaWdpbgojJyBAcGFyYW0gZW5kIC0gZW5kaW5nIG9mIHZhbGlkYXRpb24gc2V0CiMnIEBwYXJhbSB0YXUgLSBWYVIgaW4gcXVlc3Rpb24KIycgQHBhcmFtIGxvd19tIC0gbG93IHZhbHVlIG9mIG0gdG8gY29uc2lkZXIKIycgQHBhcmFtIGhpZ2hfbSAtIGhpZ2ggdmFsdWUgb2YgbSB0byBjb25zaWRlcgojJwojJyBAcmV0dXJuIC0gcmV0dXJucyB0aGUgb3B0aW1hbCB2YWx1ZSBvZiBtCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gb3B0X20ocGNfZGZbLDFdLCBwY19kZlssLTFdLCA3NTcsIDEwMjcsIDAuMDEsIGxvd19tID0xLCBoaWdoX20gID0gNSkKb3B0X20gPSBmdW5jdGlvbih5LCB4LCBvcmlnLCBlbmQgPSBOVUxMLCB0YXUsIGxvd19tID0gMSwgaGlnaF9tLCBtb2RfZGkgPSAwLCBhcl90ZiA9IDEsIHAgPSAxLCBwcmludF9tZGwgPSAwLCBtb2RlbCA9IDEsIHJvd25hbWUgPSBOVUxMKXsKICAjIEluaXRpYWxpemUgYSBsb3NzIHZlY3RvcgogIGxvc3NfdmVjID0gcmVwKDAsaGlnaF9tLWxvd19tICsgMSkKICAjIEluaXRpYWxpemUgYW4gbSB2ZWN0b3IKICBtX3ZlYyA9IHNlcShsb3dfbSwgaGlnaF9tLCBieSA9IDEpCiAgIyBMb29wIHRocm91Z2ggYW5kIHBvcHVsYXRlIHRoZSBsb3NzIHZlY3RvcgogIGZvciAoaSBpbiAxOmxlbmd0aChsb3NzX3ZlYykpewogICAgbG9zc192ZWNbaV0gPSBxdWlldChsb3NzX2NhbGMoeT15LHg9eCxvcmlnPW9yaWcsZW5kPWVuZCwgbSA9IG1fdmVjW2ldLCB0YXUgPSB0YXUsIG1vZF9kaSA9IG1vZF9kaSwgYXJfdGYgPSBhcl90ZiwgcCA9IHAsIHByaW50X21kbCA9IHByaW50X21kbCwgbW9kZWwgPSBtb2RlbCkpW1sxXV0KICB9CiAgIyBGaW5kIHRoZSBtaW5pbWl6ZXIKICBvcHRfbSA9IHdoaWNoLm1pbihsb3NzX3ZlYykKICBvcHRfcCA9IE5BCiAgIyBDb21iaW5lIGludG8gYSBkYXRhIGZyYW1lCiAgZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKG9wdF9tLCBvcHRfcCkpCiAgbmFtZXMoZGYpIDwtIGMoIk9wdGltYWwgbSIsICJPcHRpbWFsIHAiKQogICMgQXNzaWduIGEgcm93bmFtZQogIGlmIChpcy5udWxsKHJvd25hbWUpID09IFRSVUUpewogICAgIyBXcml0ZSB0aGUgcm93IG5hbWVzCiAgICByb3duYW1lcyhkZikgPC0gYygiTVYgQ0FWaWFSIikKICB9CiAgZWxzZSB7CiAgICByb3duYW1lcyhkZikgPC0gcm93bmFtZQogIH0KICAjIFJldHVybiB0aGUgbG9zc192ZWN0b3IgYW5kIHRoZSBtaW5pbXplcgogIHJldHVybihsaXN0KG9wdF9tLCBsb3NzX3ZlYywgZGYpKQp9CmBgYAoKYGBge3J9CiMnIEZ1bmN0aW9uIHRoYXQgc2VsZWN0cyB0aGUgb3B0aW1hbCBudW1iZXIgb2YgbGFncwojJwojJyBAcGFyYW0geSAtIHJlc3BvbnNlIHZlY3RvcgojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIGVuZCAtIGVuZGluZyBvZiB2YWxpZGF0aW9uIHNldAojJyBAcGFyYW0gdGF1IC0gVmFSIGluIHF1ZXN0aW9uCiMnIEBwYXJhbSBsb3dfbSAtIGxvdyB2YWx1ZSBvZiBtIHRvIGNvbnNpZGVyCiMnIEBwYXJhbSBoaWdoX20gLSBoaWdoIHZhbHVlIG9mIG0gdG8gY29uc2lkZXIKIycKIycgQHJldHVybiAtIHJldHVybnMgdGhlIG9wdGltYWwgdmFsdWUgb2YgbQojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIG9wdF9tcCh5ID0gcGNfZGZbLDFdLCB4ID0gcGNfZGZbLC0xXSwgb3JpZyA9IDc1NywgZW5kID0gMTAwNywgdGF1ID0gMC4wMSwgbG93X20gPTEsIGhpZ2hfbSAgPSA1LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCBhcl90ZiA9IDIsIG1vZF9kaSA9IDEpCm9wdF9tcCA9IGZ1bmN0aW9uKHksIHgsIG9yaWcsIGVuZCA9IE5VTEwsIHRhdSwgbG93X20gPSAxLCBoaWdoX20sIGxvd19wID0gMSwgaGlnaF9wLCBtb2RfZGkgPSAwLCBhcl90ZiA9IDEsIHByaW50X21kbCA9IDAsIG1vZGVsID0gMSwgcHJpbnRfbXAgPSAwLCByb3duYW1lID0gTlVMTCl7CiAgIyBJbml0aWFsaXplIGEgbG9zcyBtYXRyaXgKICBsb3NzX21hdCA9IG1hdHJpeCgwLCBoaWdoX3AtbG93X3AgKyAxLGhpZ2hfbS1sb3dfbSArIDEpCiAgIyBJbml0aWFsaXplIGEgcCB2ZWN0b3IKICBwX3ZlYyA9IHNlcShsb3dfcCwgaGlnaF9wLCBieSA9IDEpCiAgIyBMb29wIHRocm91Z2ggYW5kIHBvcHVsYXRlIHRoZSBsb3NzIHZlY3RvcgogIGZvciAoaSBpbiAxOm5yb3cobG9zc19tYXQpKXsKICAgIGxvc3NfbWF0W2ksXSA9IG9wdF9tKHkgPSB5LCB4ID0geCwgb3JpZyA9IG9yaWcsIGVuZCA9IGVuZCwgdGF1ID0gdGF1LCBsb3dfbSA9IGxvd19tLCBoaWdoX20gID0gaGlnaF9tLCBwID0gaSwgbW9kX2RpID0gbW9kX2RpLCBhcl90ZiA9IGFyX3RmLCBwcmludF9tZGwgPSBwcmludF9tZGwsIG1vZGVsID0gbW9kZWwpW1syXV0KICB9CiAgIyBGaW5kIHRoZSBtaW5pbWl6ZXIKICBvcHRfcCA9IHdoaWNoKGxvc3NfbWF0ID09IG1pbihsb3NzX21hdCksIGFyci5pbmQgPSBUUlVFKVsxLDFdCiAgb3B0X20gPSB3aGljaChsb3NzX21hdCA9PSBtaW4obG9zc19tYXQpLCBhcnIuaW5kID0gVFJVRSlbMSwyXQogICMgUHJpbnQgdGhlIG9wdGltYWwgcCBhbmQgb3B0aW1hbCBtCiAgZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKG9wdF9tLCBvcHRfcCkpCiAgbmFtZXMoZGYpIDwtIGMoIk9wdGltYWwgbSIsICJPcHRpbWFsIHAiKQogICMgQXNzaWduIGEgcm93bmFtZQogIGlmIChpcy5udWxsKHJvd25hbWUpID09IFRSVUUpewogICAgaWYgKGFyX3RmID09IDEpewogICAgICAjIFdyaXRlIHRoZSByb3cgbmFtZXMKICAgICAgcm93bmFtZXMoZGYpIDwtIGMoIk1WIENBVmlhUiArIEFSIikKICAgIH0gZWxzZSBpZiAoYXJfdGYgPT0gMil7CiAgICAgICMgV3JpdGUgdGhlIHJvdyBuYW1lcwogICAgICByb3duYW1lcyhkZikgPC0gYygiTVYgQ0FWaWFSICsgU0FWIikKICAgIH0gZWxzZSBpZiAoYXJfdGYgPT0gMyl7CiAgICAgICMgV3JpdGUgdGhlIHJvdyBuYW1lcwogICAgICByb3duYW1lcyhkZikgPC0gYygiTVYgQ0FWaWFSICsgQVMiKQogICAgfSBlbHNlIHsKICAgICAgcm93bmFtZXMoZGYpIDwtIGMoIlVua25vd24gTW9kZWwiKQogICAgfQogIH0KICBlbHNlIHsKICAgIHJvd25hbWVzKGRmKSA8LSByb3duYW1lCiAgfQogICMgUHJpbnQgdGhlIGRmIGlmIHRoZSBvcHRpb24gaXMgdHVybmVkIG9uCiAgaWYgKHByaW50X21wID09IDEpewogICAgcHJpbnQoZGYpCiAgfQogICMgUmV0dXJuIHRoZSBsb3NzX3ZlY3RvciBhbmQgdGhlIG1pbmltemVyCiAgcmV0dXJuKGxpc3Qob3B0X20sIG9wdF9wLCBsb3NzX21hdCwgZGYpKQp9CmBgYAoKCmBgYHtyfQojJyBBIGZ1bmN0aW9uIHRoYXQgY29tYmluZXMgb3B0aW1hbCB2YWx1ZXMgb2YgbSBhbmQgcCBpbnRvIGEgZmluYWwgdGFibGUKIycKIycgQHBhcmFtIG0xIC0gdGhlIGRhdGEgZnJhbWUgZnJvbSB0aGUgIk1WIENBVmlhUiIgcnVuCiMnIEBwYXJhbSBtMiAtIHRoZSBkYXRhIGZyYW1lIGZyb20gdGhlICJNViBDQVZpYVIgKyBBUiIgcnVuCiMnIEBwYXJhbSBtMyAtIHRoZSBkYXRhIGZyYW1lIGZyb20gdGhlICJNViBDQVZpYVIgKyBTQVYiIHJ1bgojJyBAcGFyYW0gbTQgLSB0aGUgZGF0YSBmcmFtZSBmcm9tIHRoZSAiTVYgQ0FWaWFSICsgQVMiIHJ1bgojJwojJyBAcmV0dXJuIC0gYSBuaWNlbHkgZm9ybWF0dGVkIHRhYmxlCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gcHJldHR5X3BtKG9wdF9wcmVkX25sW1szXV0sIG9wdF9wbV9tMVtbNF1dLCBvcHRfcG1fbTJbWzRdXSwgb3B0X3BtX20zW1s0XV0pCnByZXR0eV9wbSA9IGZ1bmN0aW9uKG0xLCBtMiwgbTMsIG00KXsKICAjIE1lcmdlIHRoZSBpbmRpdmlkdWFsIGRhdGEgZnJhbWVzCiAgcG1fcHJldHR5X2RmID0gcmJpbmQobTEsIG0yLCBtMywgbTQpCiAgIyBGb3JtYXQgbmljZWx5CiAgcG1fcHJldHR5X2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgTnVtYmVyIG9mIERpZmZ1c2lvbiBJbmRpY2VzIChtKSBhbmQgTGFncyAocCkgZm9yIERpZmZlcmVudCBNb2RlbHMiLCBkaWdpdHMgPSAwKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIlRoZSBNViBDQVZpYVIgbW9kZWwgZG9lc24ndCBoYXZlIGFuIG9wdGltYWwgdmFsdWUgZm9yIHAgYmVjYXVzZSB0aGVyZSBhcmUgbm8gQVIgbGFncyBpbiB0aGUgbW9kZWwiCiAgKQogIAp9CgpgYGAKCgpgYGB7cn0KIycgSGVyZSBpcyBhIGZ1bmN0aW9uIHRoYXQgcnVucyB0aGUgdW5pdmFyaWF0ZSBDQVZpYVIgbW9kZWwgNCB0aW1lcwojJwojJyBAcGFyYW0gZGYgLSB0aGUgcGVyY2VudCBjaGFuZ2UgZGF0YSBmcmFtZSB0byBjb25zaWRlcgojJyBAcGFyYW0gbmZjc3QgLSBudW1iZXIgb2YgZm9yZWNhc3RzIHRvIHJ1bgojJyBAcGFyYW0gdGF1IC0gdGhlIFZhUiBsZXZlbCB0byBjb25zaWRlcgojJyBAcGFyYW0gbm9fcnVuIC0gc3BlY2lmaWVzIGlmIGFueSBtb2RlbHMgc2hvdWxkIG5vdCBiZSBydW4KIycKIycgQHJldHVybiAtIGEgbGlzdCBvZiB0aGUgNCB1bml2YXJpYXRlIG1vZGVsIGZvcmVjYXN0cwojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGFjZWcgPSBnZW5fdXZfdGVzdChwY19kZiwgMSwgMC4wNSwgbm9fcnVuID0gYygxLDEsMCwxKSkKZ2VuX3V2X3Rlc3QgPSBmdW5jdGlvbihkZiwgbmZjc3QsIHRhdSwgbm9fcnVuID0gYygwLDAsMCwwKSl7CiAgIyBtb2RlbCB0eXBlICgxIC0gU0FWLCAyIC0gQVMsIDMgLSBHQVJDSCwgNCAtIEFEQVBUSVZFKSAKICAjIEluaXRpYWxpemUgYSBsaXN0ICAKICBvdXRfbGlzdCA9IGxpc3QoKQogICMgUnVuIHRoZSBmb3VyIG1vZGVscyAtIG1vZGVsIDE7IFNBVgogIGlmIChub19ydW5bMV0gPT0gMCl7CiAgICB1dmNhdl8xID0gcm9sbGluZ19wcmVkaWN0aW9ucyhkZlssMV0sIHJhbmdlX2RhdGEgPSAoMTpsZW5ndGgoZGZbLDFdKSksIG5mY3N0ID0gbmZjc3QsIG1vZGVsID0gMSwgRyA9IDEwLCBjb2wgPSAxLCBsZXZlbCA9IHRhdSkKICB9CiAgIyBBZGQgYSBmaWxsZXIgaWYgdGhlcmUncyBubyBlbnRyeQogIGVsc2UgewogICAgdXZjYXZfMSA9IDAKICB9CiAgIyBNb2RlbCAyIC0gQVMKICBpZiAobm9fcnVuWzJdID09IDApewogICAgdXZjYXZfMiA9IHJvbGxpbmdfcHJlZGljdGlvbnMoZGZbLDFdLCByYW5nZV9kYXRhID0gKDE6bGVuZ3RoKGRmWywxXSkpLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IDIsIEcgPSAxMCwgY29sID0gMSwgbGV2ZWwgPSB0YXUpCiAgfQogIGVsc2UgewogICAgdXZjYXZfMiA9IDAKICB9CiAgIyBNb2RlbCAzIC0gR0FSQ0gKICBpZiAobm9fcnVuWzNdID09IDApewogICAgdXZjYXZfMyA9IHJvbGxpbmdfcHJlZGljdGlvbnMoZGZbLDFdLCByYW5nZV9kYXRhID0gKDE6bGVuZ3RoKGRmWywxXSkpLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IDMsIEcgPSAxMCwgY29sID0gMSwgbGV2ZWwgPSB0YXUpCiAgfQogIGVsc2UgewogICAgdXZjYXZfMyA9IDAKICB9CiAgIyBNb2RlbCA0IC0gQWRhcHRpdmUKICBpZiAobm9fcnVuWzRdID09IDApewogICAgdXZjYXZfNCA9IHJvbGxpbmdfcHJlZGljdGlvbnMoZGZbLDFdLCByYW5nZV9kYXRhID0gKDE6bGVuZ3RoKGRmWywxXSkpLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IDQsIEcgPSAxMCwgY29sID0gMSwgbGV2ZWwgPSB0YXUpCiAgfQogIGVsc2UgewogICAgdXZjYXZfNCA9IDAKICB9CiAgIyBFeHBvcnQgdGhlIGRhdGEgYXMgYSBsaXN0CiAgcmV0dXJuKGxpc3QodXZjYXZfMSwgdXZjYXZfMiwgdXZjYXZfMywgdXZjYXZfNCkpCn0KCmBgYAoKYGBge3J9CiMnIEZ1bmN0aW9uIHRvIHBsb3QgdGhlIGRhdGEgd2hpY2ggd2UgZ2VuZXJhdGUgaW4gcHJldmlvdXMgZnVuY3Rpb25zCiMnCiMnIEBwYXJhbSBwbG90X21hdHJpeCAtIG1hdHJpeCB3aXRoIHRoZSBkYXRhIHRvIHBsb3QKIycgQHBhcmFtIG5vcm1fdmFsdWUgLSB3aGF0IHRvIHN1YnRhY3QgZnJvbSB0aGUgZGF0YSB0byBtYWtlIGl0IG9uIGEgcGVyY2VudGFnZSBjaGFuZ2UgYmFzaXMuIERlZmF1bHQgaXMgMTAwLgojJwojJyBAcmV0dXJuIAojJyBAZXhwb3J0IC0gYSBwbG90IG9mIHRoZSBkYXRhIGJ5IGRpZmZ1c2lvbiBpbmRleCBudW1iZXIKIycKIycgQGV4YW1wbGVzID0gcGx0X2RhdGEocGxvdF9tdHhbWzFdXSksIGFiYyA9IHBsdF9kYXRhKHBsb3RfbWF0LCB0YXUgPSAwLjAxKQpwbHRfZGF0YSA9IGZ1bmN0aW9uKHBsb3RfbWF0cml4LCB0YXUsIHJlc3BfdmFyLCBudGVzdCl7CiAgIyBFc3RhYmxpc2ggYSBtYXhpbXVtIGFuZCBtaW5pbXVtIHZhbHVlCiAgbWF4X3ZhbCA9IG1heChwbG90X21hdHJpeFssMTpuY29sKHBsb3RfbWF0cml4KV0pCiAgbWluX3ZhbCA9IG1pbihwbG90X21hdHJpeFssMTpuY29sKHBsb3RfbWF0cml4KV0pCiAgIyBDYWxjdWxhdGUgaW5pdGFsIGFuZCBlbmRpbmcgdGltZSB2YWx1ZQogIHN0YXJ0ID0gaW5kZXgocGxvdF9tYXRyaXgpWzFdCiAgZW5kID0gaW5kZXgocGxvdF9tYXRyaXgpW25yb3cocGxvdF9tYXRyaXgpXQogIGluZF92YWxzID0gaW5kZXgocGxvdF9tYXRyaXgpIC0gc3RhcnQKICAjIENyZWF0ZSBhbiBpbml0aWFsIHBsb3QgYW5kIGFkZCBsaW5lcwogICAgZm9yIChpIGluIDE6bmNvbChwbG90X21hdHJpeCkpewogICAgICBpZiAoaSA9PSAxKXsKICAgICAgICAjIDQvMi8yMDIwIC0gZml4aW5nIHRoZSBpbmRleAogICAgICAgIHBsb3QudHMoaW5kX3ZhbHMscGxvdF9tYXRyaXhbLGldLCB0eXBlID0gImwiLCB4bGFiID0gcGFzdGUoIkRheXMgU2luY2UiLCBhcy5EYXRlKHN0YXJ0KSksIHlsYWIgPSAiUGVyY2VudCBDaGFuZ2UgaW4gUEciLCB5bGltID0gYyhtaW5fdmFsLG1heF92YWwpLCBsd2QgPSAxLCBtYWluID0gcGFzdGUoIlByZWRpY3RpbmciLCByZXNwX3ZhciwgIlJldHVybnMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpLCBzdWIgPSBwYXN0ZSgiVGhlIFZhUiBMZXZlbCBpcyAiLCAxMDAqdGF1LCAiJSIsICI7IFRoZXJlIGFyZSAiLCBudGVzdCwgIiBUcmFkaW5nIERheXMgUGxvdHRlZCBBYm92ZSIsIHNlcCA9ICIiKSkKICAgICAgICAjIHBsb3QudHMoaW5kZXgocGxvdF9tYXRyaXgpLCBwbG90X21hdHJpeFssaV0sIHR5cGUgPSAibCIsIHhsYWIgPSAiVHJhZGluZyBEYXlzIiwgeWxhYiA9ICJQZXJjZW50IENoYW5nZSBpbiBQRyIsIHlsaW0gPSBjKG1pbl92YWwsbWF4X3ZhbCksIGx3ZCA9IDEsIG1haW4gPSAiUHJlZGljdGluZyBQRyBSZXR1cm5zIE92ZXIgTGFzdCAyNTAgVHJhZGluZyBEYXlzIGluIDIwMDgiLCBzdWIgPSBwYXN0ZSgiVGhlIFZhUiBMZXZlbCBpcyAiLCAxMDAqdGF1LCAiJSIsIHNlcCA9ICIiKSkKICAgIH0gZWxzZSBpZihpICVpbiUgc2VxKDIsOCwxKSkgewogICAgICAgIGxpbmVzKGluZF92YWxzLHBsb3RfbWF0cml4WyxpXSwgY29sID0gaS0xLCBsdHkgPSAyKQogICAgfSBlbHNlIHsKICAgICAgICBsaW5lcyhpbmRfdmFscyxwbG90X21hdHJpeFssaV0sIGNvbCA9IGktMSwgbHR5ID0gMiwgbHdkID0gMikKICAgIH0KICAgIH0KICAjIERlZmluZSBhIHNlcXVlbmNlIGZvciBwbG90dGluZwogIHBsb3Rfc2VxID0gc2VxKDEsIG5jb2wocGxvdF9tYXRyaXgpKQogIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoY29sbmFtZXMocGxvdF9tYXRyaXgpKSwgY29sID0gcGxvdF9zZXEsIGx0eSA9IGMoMSwgcmVwKDIsIDcpLCByZXAoMywgaWZlbHNlKG5jb2wocGxvdF9tYXRyaXgpLTggPD0gMCwgMCwgbmNvbChwbG90X21hdHJpeCktOCkpKSwgbHdkID0gYygxLCByZXAoMSwgNyksIHJlcCgyLCBpZmVsc2UobmNvbChwbG90X21hdHJpeCktOCA8PSAwLCAwLCBuY29sKHBsb3RfbWF0cml4KS04KSkpKQogICMgQWRkIGEgbGluZSBmb3IgMAogICMgYWJsaW5lKGggPSAwLCBjb2wgPSAiYmxhY2siLCBsdHkgPSAyKQp9CgoKYGBgCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgbG9zc2VzIGJhc2VkIG9uIHRoZSB0ZXN0IHNhbXBsZQojJwojJyBAcGFyYW0gdHJ1ZV92ZWMgLSB0aGUgdHJ1ZSB2ZWN0b3Igb2YgcmV0dXJucwojJyBAcGFyYW0gcHJlZF92ZWMgLSB0aGUgcHJlZGljdGVkIHZlY3RvciBmcm9tIHRoZSBtb2RlbCBydW5zCiMnIEBwYXJhbSB0YXUgLSBWYVIgbGV2ZWwuIE11c3QgbWF0Y2ggd2hhdCB0aGUgbW9kZWwgdXNlZAojJwojJyBAcmV0dXJuIC0gdG90YWwgbG9zc2VzIGFuZCB0aGUgZW50aXJlIGxvc3MgdmVjdG9yCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzCmxvc3NfdGVzdCA9IGZ1bmN0aW9uKHRydWVfdmVjLCBwcmVkX3ZlYywgdGF1KXsKICAjIEluaXRpYWxpemUgYSBsb3NzIHZlY3RvcgogIGx2ZWMgPSByZXAoMCwgbGVuZ3RoKHRydWVfdmVjKSkKICAjIEluaXRpYWxpemUgYSBicmVhayB2ZWN0b3IgdG8gc2VlIHdoZW4gVmFSIGlzIGJyb2tlbgogIGJ2ZWMgPSByZXAoMCwgbGVuZ3RoKHRydWVfdmVjKSkKICBmb3IgKGkgaW4gMTpsZW5ndGgodHJ1ZV92ZWMpKXsKICAgICMgQ2FsY3VsYXRlIGFuIGluZGljYXRvciB2YXJpYWJsZQogICAgYnZlY1tpXSA9IGlmZWxzZSh0cnVlX3ZlY1tpXSA8IHByZWRfdmVjW2ldLCAxLDApCiAgICAjIFVzZSBpbmRpY2F0b3IgaW4gZnVuY3Rpb24gYmVsb3cKICAgIGx2ZWNbaV0gPSAodGF1IC0gYnZlY1tpXSkqKHRydWVfdmVjW2ldIC0gcHJlZF92ZWNbaV0pCiAgfQogICMgQWRkIHVwIHRoZSBsb3NzZXMKICAjIHN1bWxvc3MgPSBzdW0obHZlYykvbGVuZ3RoKGx2ZWMpCiAgc3VtbG9zcyA9IHN1bShsdmVjKQogICMgQWRkIHVwIHRoZSBWYVIgYnJlYWthZ2UKICB2YXJicmVhayA9IHN1bShidmVjKS9sZW5ndGgoYnZlYykKICByZXR1cm4obGlzdChzdW1sb3NzLGx2ZWMsIHZhcmJyZWFrLCBidmVjKSkKfQpgYGAKCgoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGxvc3NlcyBiYXNlZCBvbiB0aGUgcGxvdCBtYXRyaXgKIycKIycgQHBhcmFtIGRhdGFfbWF0IC0gYSBtYXRyaXggb2YgZm9yZWNhc3RlZCBWYVIgdmFsdWVzLCB3aXRoIHRoZSB0cnVlIHZhbHVlIGluIHRoZSBmaXJzdCBjb2x1bW4KIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbC4gTXVzdCBtYXRjaCB3aGF0IHRoZSBtb2RlbCB1c2VkCiMnCiMnIEByZXR1cm4gLSBhIGxpc3Qgb2YgZm91ciBpdGVtcy4gCiMnIDEgPSBhIHZlY3RvciBvZiB0aGUgbG9zc2VzIG9mIGFsbCBtb2RlbHMuIAojJyAyID0gYSB2ZWN0b3Igc2hvd2luZyB0aGUgcGVyY2VudGFnZSBvZiBWYVIgYnJlYWtzIGJ5IG1vZGVsCiMnIDMgPSB0aGUgbG9zcyBtYXRyaXgKIycgNCA9IHRoZSBicmVhayBtYXRyaXgKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKZ2VuX2xvc3NfdGVzdCA9IGZ1bmN0aW9uKGRhdGFfbWF0LCB0YXUpewogICMgSW5pdGlhbGl6ZSBsb3NzIGFuZCBicmVhayBtYXRyaWNlcwogIGxtYXQgPSBibWF0ID0gbWF0cml4KDAsIG5yb3cgPSBucm93KGRhdGFfbWF0KSwgbmNvbCA9IG5jb2woZGF0YV9tYXQpLTEpCiAgIyBidmVjID0gcmVwKDAsIGxlbmd0aCh0cnVlX3ZlYykpCiAgIyBQb3B1bGF0ZSB0aGUgbWF0cmljZXMKICBmb3IgKGkgaW4gMTpucm93KGxtYXQpKXsKICAgIGZvciAoaiBpbiAxOihuY29sKGxtYXQpKSl7CiAgICAgICMgQ2FsY3VsYXRlIGFuIGluZGljYXRvciB2YXJpYWJsZQogICAgICBibWF0W2ksal0gPSBpZmVsc2UoZGF0YV9tYXRbaSwxXSA8IGRhdGFfbWF0W2ksaisxXSwgMSwwKQogICAgICAjIFVzZSBpbmRpY2F0b3IgaW4gZnVuY3Rpb24gYmVsb3cKICAgICAgbG1hdFtpLGpdID0gKHRhdSAtIGJtYXRbaSxqXSkqKGRhdGFfbWF0W2ksMV0gLSBkYXRhX21hdFtpLGorMV0pCiAgICB9ICAgIAogIH0KICAjIEFkZCB1cCB0aGUgbG9zc2VzCiAgc3VtbG9zcyA9IGNvbFN1bXMobG1hdCkKICAjIEFkZCB1cCB0aGUgVmFSIGJyZWFrYWdlCiAgdmFyYnJlYWsgPSBjb2xTdW1zKGJtYXQpL25yb3coYm1hdCkKICByZXR1cm4obGlzdChzdW1sb3NzLCB2YXJicmVhaywgbG1hdCwgYm1hdCkpCn0KYGBgCgoKCmBgYHtyfQojJyBBIGZ1bmN0aW9uIHRvIG1ha2UgYSBuaWNlIGNvbXBhcmlzb24gb2YgbG9zc2VzCiMnCiMnIEBwYXJhbSBkYXRhX21hdCAtIGlucHV0IGRhdGEgbWF0cml4IHVzZWQgaW4gdGhlIGNhbGN1bGF0aW9uIG9mIGxvc3NlcwojJyBAcGFyYW0gbG9zc19saXN0IC0gYSBsaXN0IG9mIHRoZSBsb3NzZXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBDQVZpYVIgZnVuY3Rpb24KIycgQHBhcmFtIHRhdSAtIHRoZSByaXNrIGxldmVsIHVzZWQKIycgQHBhcmFtIG50ZXN0IC0gdGhlIG51bWJlciBvZiB0ZXN0IHBvaW50cwojJwojJyBAcmV0dXJuCiMnIEBleHBvcnQgLSByZXR1cm5zIGEgbmljZWx5IGZvcm1hdHRlZCB0YWJsZQojJwojJyBAZXhhbXBsZXMgLSBwcmV0dHlfdGFibGVzKHBsb3RfbWF0LCBsX2xpc3QsIHRhdSA9IDAuMDEpCnByZXR0eV90YWJsZXMgPSBmdW5jdGlvbihkYXRhX21hdCwgbG9zc19saXN0LCB0YXUsIG50ZXN0KXsKICAjIENvbWJpbmUgaW50byBhIGRhdGEgZnJhbWUKICBkZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQobG9zc19saXN0W1sxXV0sIGxvc3NfbGlzdFtbMl1dKSkKICAjIENhbGN1bGF0ZSBpbml0YWwgYW5kIGVuZGluZyB0aW1lIHZhbHVlCiAgc3RhcnQgPSBpbmRleChkYXRhX21hdClbMV0KICBlbmQgPSBpbmRleChkYXRhX21hdClbbnJvdyhkYXRhX21hdCldCiAgIyBBZGQgcm93L2NvbHVtbiBuYW1lcwogIGNvbG5hbWVzKGRmKSA8LSBjb2xuYW1lcyhkYXRhX21hdFssLTFdKQogIHJvd25hbWVzKGRmKSA8LSBjKCJMb3NzZXMiLCAiVmFSIEJyZWFrcyAoJSkiKQogICMgQ29udmVydCB0byBhIHRhYmxlCiAgZGYgJT4lIGthYmxlKGNhcHRpb24gPSBwYXN0ZSgiQ29tcGFyaXNvbiBvZiBWYVIgTWV0aG9kcyBmb3IgYSAiLCB0YXUqMTAwLCAiJSBWYVIiLCBzZXAgPSAiIiksIGRpZ2l0cyA9IDMpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSBwYXN0ZSgiQ2FsY3VsYXRlZCB1c2luZyIsIG50ZXN0LCAidHJhZGluZyBkYXlzIGZyb20iLCBhcy5EYXRlKHN0YXJ0KSwgInRvIiwgYXMuRGF0ZShlbmQpKSkKfQpgYGAKCmBgYHtyfQojJyBBIGRyZXNzZWQgdXAgdmVyc2lvbiBvZiB0aGUgZXhwb3J0IGZ1bmN0aW9uCiMnCiMnIEBwYXJhbSB2YXJfZmlsZSAtIGZpbGUgdG8gZXhwb3J0CiMnIEBwYXJhbSBwYXRoIC0gZmlsZXBhdGgKIycgQHBhcmFtIGZpbGVuYW1lIC0gbmFtZSBvZiB0aGUgZmlsZSwgZW5kaW5nIHdpdGggLkNTVgojJwojJyBAcmV0dXJuCiMnIEBleHBvcnQgLSBleHBvcnRlZCBDU1YgZmlsZQojJwojJyBAZXhhbXBsZXMgLSBleHBfZnVuYyh2YXJfZmlsZSA9IHZhcl8xcGNfMjAxNl91c2V0ZltbMV1dLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAiVEVTVC5jc3YiKQpleHBfZnVuYyA9IGZ1bmN0aW9uKHZhcl9maWxlLCBwYXRoLCBmaWxlbmFtZSl7CiAgIyBXcml0ZSBhIHpvbwogIHdyaXRlLnpvbyh2YXJfZmlsZSwgcGFzdGUwKHBhdGgsIGZpbGVuYW1lKSwgcXVvdGUgPSBGQUxTRSwgc2VwID0gIiwiKQp9CgojIGV4cF9mdW5jKHZhcl9maWxlID0gdmFyXzFwY18yMDE2X3VzZXRmW1sxXV0sIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJURVNULmNzdiIpCgpgYGAKCgoKCiMgQmlnIFNpbXVsYXRpb24gRnVuY3Rpb24KCmBgYHtyfQojJyBUaGlzIGlzIHRoZSAibWFzdGVyIiBmdW5jdGlvbiB3aGVyZSB3ZSdsbCBldmFsdWF0ZSB0aGUgaW1wb3J0YW5jZSBvZiB0aGUgVmFSIG1vZGVsIG92ZXIgc2V2ZXJhbCB0aW1lIHBlcmlvZHMKIycKIycgQHBhcmFtIHN5bWJvbF9saXN0IC0gYSBsaXN0IG9mIHN5bWJvbHMgdG8gZmVlZCBpbnRvIHRoZSBtb2RlbCAKIycgQHBhcmFtIHJlc3BfdmFyIC0gdGhlIHJlc3BvbnNlIHZhcmlhYmxlCiMnIEBwYXJhbSBjb21wbF9jYXNlIC0gc2hvdWxkIHRoZSBtb2RlbCByZXF1aXJlIGNvbXBsZXRlIGNhc2VzPyBEZWZhdWx0IHZhbHVlIGlzIDEuCiMnIEBwYXJhbSBhZGpfY2xvc2UgLSB1c2UgYWRqdXN0ZWQgY2xvc2UgcHJpY2UgZm9yIHRoZSBwcmVkaWN0b3JzPyBEZWZhdWx0IHZhbHVlIGlzIDEuCiMnIEBwYXJhbSByZXNwX2Fkal9jbG9zZSAtIHVzZSBhZGp1c3RlZCBjbG9zZSBwcmljZSBmb3IgdGhlIHJlc3BvbnNlPyBEZWZhdWx0IHZhbHVlIGlzIDEuCiMnIEBwYXJhbSBzdGFydF9kYXRlIC0gc3RhcnQgZGF0ZSB0byBwdWxsIGRhdGEgZnJvbQojJyBAcGFyYW0gZW5kX2RhdGUgLSBlbmQgZGF0ZSB0byBwdWxsIGRhdGEgZnJvbQojJyBAcGFyYW0gbnZhbCAtIG51bWJlciBvZiB2YWxpZGF0aW9uIHBvaW50cyB0byB1c2UKIycgQHBhcmFtIG50ZXN0IC0gbnVtYmVyIG9mIHRlc3QgcG9pbnRzIHRvIHVzZQojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsIHRvIHVzZQojJyBAcGFyYW0gbG93X20gLSBsb3cgbnVtYmVyIG9mIHByZWRpY3RvcnMgdG8gdGVzdAojJyBAcGFyYW0gaGlnaF9tICAtIGxvdyBudW1iZXIgb2YgcHJlZGljdG9ycyB0byB0ZXN0CiMnIEBwYXJhbSB1dl9saXN0IC0gYSBsaXN0IG9mIGEgcHJlLXJ1biB1bml2YXJpYXRlIG1vZGVsLiBJZiBhIGRhdGEgZnJhbWUgaXMgbm90IHByb3ZpZGVkLCB0aGUgbGVuZ3RoeSB1diBtb2RlbCB3aWxsIHJ1biAKIycgQHBhcmFtIG5vX3J1biAtIHRoaW5ncyBub3QgdG8gcnVuIGluIHRoZSBtb2RlbAojJyBAcGFyYW0gbG93X3AgLSBsb3cgdmFsdWUgZm9yIG51bWJlciBvZiBsYWdzCiMnIEBwYXJhbSBoaWdoX3AgLSBoaWdoIHZhbHVlIGZvciBudW1iZXIgb2YgbGFncwojJyBAcGFyYW0gbmFfaW50ZXJwIC0gc2hvdWxkIHRoZSBmdW5jdGlvbiBpbnRlcnBvbGF0ZSBOQSdzCiMnIEBwYXJhbSBwcmludF9tZGwgLSBwcmludCB0aGUgbW9kZWwgc3VtbWFyaWVzPwojJyBAcGFyYW0gcHJpbnRfbXAgLSBwcmludCB0aGUgb3B0aW1hbCB2YWx1ZXMgZm9yIHAgYW5kIG0KIycgQHBhcmFtIGxhZ19wcmVkIC0gZG8geW91IHdhbnQgdG8gbGFnIHRoZSBtIHByZWRpY3RvcnMgKGRlZmF1bHQgaXMgMTsgc3Ryb25nbHkgcmVjb21tZW5kZWQpCiMnIEBwYXJhbSByb3duYW1lIC0gd2hhdCB0byBuYW1lIHRoZSByb3dzIG9mIHRoZSBuaWNlIHAgYW5kIG0gbWF0cml4CiMnIEBwYXJhbSBleHBvcnRfY3N2IC0gZG8geW91IHdhbnQgdG8gZXhwb3J0IGEgQ1NWPyBEZWZhdWx0IGlzIDEuCiMnIEBwYXJhbSBwYXRoIC0gcGF0aCB0byBleHBvcnQgdGhlIENTVgojJyBAcGFyYW0gZmlsZW5hbWUgLSB3aGF0IHRvIG5hbWUgdGhlIENTVgojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIHRoZSBwbG90IG1hdHJpeCwgYSBwbG90LCBhIGxpc3Qgd2l0aCBsb3NzZXMsIGFuZCBhIHRhYmxlCiMnIEBleHBvcnQgLSBhIHBsb3QgYW5kIGEgdGFibGUKIycKIycgQGV4YW1wbGVzIC0gY2F2X3NpbXVsKGMoIkRJUyIsICJHRSIsICJJQk0iLCAiTU1NIiwgIlhPTSIpLCByZXNwX3ZhciA9ICJQRyIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA1LCB0YXUgPSAwLjAxLCB1dl9saXN0ID0gdXZfY2F2X2xpc3QpCmNhdl9zaW11bCA9IGZ1bmN0aW9uKHN5bWJvbF9saXN0LCByZXNwX3ZhciwgY29tcGxfY2FzZSA9IDEsIGFkal9jbG9zZSA9IDEsIHJlc3BfYWRqX2Nsb3NlID0gMSwgc3RhcnRfZGF0ZSA9ICIxOTAwLTAxLTAxIiwgZW5kX2RhdGUgPSBTeXMuRGF0ZSgpLCBudmFsLCBudGVzdCwgdGF1LCBsb3dfbSA9IDEsIGhpZ2hfbSwgbG93X3AgPSAxLCBoaWdoX3AsIHV2X2xpc3QgPSBOVUxMLCBub19ydW4gPSBjKDAsMCwwLDApLCBuYV9pbnRlcnAgPSBUUlVFLCBwcmludF9tZGwgPSAwLCBwcmludF9tcCA9IDAsIGxhZ19wcmVkID0gMSwgcm93bmFtZSA9IE5VTEwsIGV4cG9ydF9jc3YgPSAxLCBwYXRoLCBmaWxlbmFtZSl7CiAgIyBTZWxlY3QgZGF0YSBwYXJhbWV0ZXJzLCBwdWxsIHRoZSBkYXRhLCBhbmQgcGVyY2VudCBjaGFuZ2UgdGhlIGRhdGEKICBkZiA9IGRpZmZfaW5kZXhfZGYoc3ltYm9sX2xpc3QgPSBzeW1ib2xfbGlzdCwgcmVzcF92YXIgPSByZXNwX3ZhciwgY29tcGxfY2FzZSA9IGNvbXBsX2Nhc2UsIGFkal9jbG9zZSA9IGFkal9jbG9zZSwgcmVzcF9hZGpfY2xvc2UgPSByZXNwX2Fkal9jbG9zZSwgc3RhcnRfZGF0ZSA9IHN0YXJ0X2RhdGUsIGVuZF9kYXRlID0gZW5kX2RhdGUsIGxhZ19wcmVkID0gbGFnX3ByZWQpCiAgIyBUYWtlIHRoZSBwZXJjZW50IGNoYW5nZSBvZiB0aGUgZGF0YQogIHBjX2RmID0gcGNfZGlmZl9pbmRleChkZikKICAjIEV4dHJhY3QgdGhlIGxlZ250aCBvZiB0aGUgZGF0YSBmcmFtZQogIG5yID0gdGVzdF9lbmQgPSBucm93KHBjX2RmKQogICMgQ2FsY3VsYXRlIHRoZSBzdGFydCBvZiB0aGUgdmFsIHBlcmlvZCwgdGhlIGVuZCBvZiB0aGUgdmFsIHBlcmlvZCwgYW5kIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0ZXN0IHBlcmlvZAogIHRlc3Rfb3JpZyA9IHRlc3RfZW5kIC0gbnRlc3QKICB2YWxfZW5kID0gdGVzdF9vcmlnCiAgdmFsX29yaWcgPSB0ZXN0X29yaWcgLSBudmFsCiAgIyBUZXN0IGZvciB0aGUgb3B0aW1hbCBudW1iZXIgb2YgcGFyYW1ldGVycwogIG9wdF9wcmVkX25sID0gb3B0X20oeSA9IHBjX2RmWywxXSwgeCA9IHBjX2RmWywtMV0sIG9yaWcgPSB2YWxfb3JpZywgZW5kID0gdmFsX2VuZCwgdGF1ID0gdGF1LCBsb3dfbSA9IGxvd19tLCBoaWdoX20gPSBoaWdoX20sIHJvd25hbWUgPSByb3duYW1lKQogIG9wdF9wcmVkX2FydDEgPSBvcHRfbXAoeSA9IHBjX2RmWywxXSwgeCA9IHBjX2RmWywtMV0sIG9yaWcgPSB2YWxfb3JpZywgZW5kID0gdmFsX2VuZCwgdGF1ID0gdGF1LCBsb3dfbSA9IGxvd19tLCBoaWdoX20gPSBoaWdoX20sIGxvd19wID0gbG93X3AsIGhpZ2hfcCA9IGhpZ2hfcCxtb2RfZGkgPSAxLCBhcl90ZiA9IDEsIHByaW50X21kbCA9IHByaW50X21kbCwgcHJpbnRfbXAgPSBwcmludF9tcCwgcm93bmFtZSA9IHJvd25hbWUpCiAgb3B0X3ByZWRfYXJ0MiA9IG9wdF9tcCh5ID0gcGNfZGZbLDFdLCB4ID0gcGNfZGZbLC0xXSwgb3JpZyA9IHZhbF9vcmlnLCBlbmQgPSB2YWxfZW5kLCB0YXUgPSB0YXUsIGxvd19tID0gbG93X20sIGhpZ2hfbSA9IGhpZ2hfbSwgbG93X3AgPSBsb3dfcCwgaGlnaF9wID0gaGlnaF9wLG1vZF9kaSA9IDEsIGFyX3RmID0gMiwgcHJpbnRfbWRsID0gcHJpbnRfbWRsLCBwcmludF9tcCA9IHByaW50X21wLCByb3duYW1lID0gcm93bmFtZSkKICBvcHRfcHJlZF9hcnQzID0gb3B0X21wKHkgPSBwY19kZlssMV0sIHggPSBwY19kZlssLTFdLCBvcmlnID0gdmFsX29yaWcsIGVuZCA9IHZhbF9lbmQsIHRhdSA9IHRhdSwgbG93X20gPSBsb3dfbSwgaGlnaF9tID0gaGlnaF9tLCBsb3dfcCA9IGxvd19wLCBoaWdoX3AgPSBoaWdoX3AsIG1vZF9kaSA9IDEsIGFyX3RmID0gMywgcHJpbnRfbWRsID0gcHJpbnRfbWRsLCBwcmludF9tcCA9IHByaW50X21wLCByb3duYW1lID0gcm93bmFtZSkKICAjIGdlbl91dl90ZXN0KHBjX2RmLCAxLCAwLjA1LCBub19ydW4gPSBjKDEsMSwwLDEpKQogICMgVXNlIHRoZSBhYm92ZSBmb3JlY2FzdHMgdG8gaW5wdXQgaW50byB0aGUgYWJvdmUKICBtdl9mY3N0ID0gbW9kX2RpKHBjX2RmWywxXSwgcGNfZGZbLC0xXSwgb3JpZyA9IHRlc3Rfb3JpZywgbSA9IG9wdF9wcmVkX25sW1sxXV0sIHRhdSA9IHRhdSwgcHJpbnRfbWRsID0gcHJpbnRfbWRsKQogIG12X2Zjc3RfYXJ0MSA9IG1vZF9kaV93bChwY19kZlssMV0sIHBjX2RmWywtMV0sIG9yaWcgPSB0ZXN0X29yaWcsIG0gPSBvcHRfcHJlZF9hcnQxW1sxXV0sIHAgPSBvcHRfcHJlZF9hcnQxW1syXV0sIHRhdSA9IHRhdSwgYXJfdGYgPSAxLCBwcmludF9tZGwgPSBwcmludF9tZGwpCiAgbXZfZmNzdF9hcnQyID0gbW9kX2RpX3dsKHBjX2RmWywxXSwgcGNfZGZbLC0xXSwgb3JpZyA9IHRlc3Rfb3JpZywgbSA9IG9wdF9wcmVkX2FydDJbWzFdXSwgcCA9IG9wdF9wcmVkX2FydDJbWzJdXSwgdGF1ID0gdGF1LCBhcl90ZiA9IDIsIHByaW50X21kbCA9IHByaW50X21kbCkKICBtdl9mY3N0X2FydDMgPSBtb2RfZGlfd2wocGNfZGZbLDFdLCBwY19kZlssLTFdLCBvcmlnID0gdGVzdF9vcmlnLCBtID0gb3B0X3ByZWRfYXJ0M1tbMV1dLCBwID0gb3B0X3ByZWRfYXJ0M1tbMl1dLCB0YXUgPSB0YXUsIGFyX3RmID0gMywgcHJpbnRfbWRsID0gcHJpbnRfbWRsKQogICMgQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgcHJlZGljdGlvbnMKICBpZiAoaXMubnVsbCh1dl9saXN0KSA9PSBUUlVFKXsKICAgICMgUHJpbnQgYSB3YXJuaW5nCiAgICBwcmludCgiV0FSTklORzogTm90IHN1cHBseWluZyBhbiBpbnB1dCBkYXRhIGZyYW1lIHdpbGwgcmVxdWlyZSB0aGlzIGZ1bmN0aW9uIHRvIHJ1biBmb3IgYSBzaWduaWZpY2FudCBhbW91bnQgb2YgdGltZSAoMWhyKykiKQogICAgIyBDYWxsIHRoZSBmdW5jdGlvbgogICAgIyBnZW5fdXZfdGVzdCA9IGZ1bmN0aW9uKGRmLCBuZmNzdCwgdGF1LCBub19ydW4gPSBjKDAsMCwwLDApKXsKICAgICMgcHJpbnQoaGVhZChwY19kZikpCiAgICB1dl9saXN0ID0gZ2VuX3V2X3Rlc3QoZGYgPSBwY19kZiwgbmZjc3QgPSBudGVzdCwgdGF1ID0gdGF1LCBub19ydW4gPSBub19ydW4pCiAgICAjIEFkZCB0byBhIGRhdGEgZnJhbWUKICAgICMgSW5jb3Jwb3JhdGUgdGhlIHJvbGxpbmcgcHJlZGljdGlvbnMgZnVuY3Rpb24gcmVzdWx0cyBoZXJlCiAgcGxvdF9tYXQgPSBjYmluZChwY19kZlsodGVzdF9vcmlnKzEpOm5yb3cocGNfZGYpLDFdLCBtdl9mY3N0JHloYXRbMTpudGVzdF0sIG12X2Zjc3RfYXJ0MSR5aGF0WzE6bnRlc3RdLCBtdl9mY3N0X2FydDIkeWhhdFsxOm50ZXN0XSwgbXZfZmNzdF9hcnQzJHloYXRbMTpudGVzdF0sIHV2X2xpc3RbWzFdXVsodGVzdF9vcmlnKzEpOnRlc3RfZW5kXSooLTEpLCB1dl9saXN0W1syXV1bKHRlc3Rfb3JpZysxKTp0ZXN0X2VuZF0qKC0xKSwgdXZfbGlzdFtbM11dWyh0ZXN0X29yaWcrMSk6dGVzdF9lbmRdKigtMSksIHV2X2xpc3RbWzRdXVsodGVzdF9vcmlnKzEpOnRlc3RfZW5kXSooLTEpKQogIH0gZWxzZSB7CiAgICAjIEFzc2lnbiB0aGUgY29sdW1ucyBvZiB0aGUgZGF0YSBmcmFtZQogICAgIyBoZWFkKHZhcl81cGNfMjAxMF91c2V0ZltbMV1dWyw2OjldKQogICAgIyBtb2RlbCB0eXBlICgxIC0gU0FWLCAyIC0gQVMsIDMgLSBHQVJDSCwgNCAtIEFEQVBUSVZFKSAKICAgICMgdGVzdF9kZiA9IGhlYWQodmFyXzVwY18yMDEwX3VzZXRmW1sxXV1bLDY6OV0pCiAgICAjIHRlc3RfZGYkU0FWCiAgICAjIHRlc3RfZGYkYEFicy4gU2xvcGVgCiAgICAjIHRlc3RfZGYkYEluZC4gR0FSQ0hgCiAgICAjIHRlc3RfZGYkQWRhcHRpdmUKICAgIHBsb3RfbWF0ID0gY2JpbmQocGNfZGZbKHRlc3Rfb3JpZysxKTpucm93KHBjX2RmKSwxXSwgbXZfZmNzdCR5aGF0WzE6bnRlc3RdLCBtdl9mY3N0X2FydDEkeWhhdFsxOm50ZXN0XSwgbXZfZmNzdF9hcnQyJHloYXRbMTpudGVzdF0sIG12X2Zjc3RfYXJ0MyR5aGF0WzE6bnRlc3RdLCB1dl9saXN0JFNBViwgdXZfbGlzdCRgQWJzLiBTbG9wZWAsIHV2X2xpc3QkYEluZC4gR0FSQ0hgLCB1dl9saXN0JEFkYXB0aXZlKQogIH0KICAjIENvdW50IHRoZSBOQXMgYW5kIHByaW50IGEgd2FybmluZwogIHByaW50KHBhc3RlKCJOT1RFOiBUaGVyZSBhcmUgIiwgc3VtKGlzLm5hKHBsb3RfbWF0KSksICIgTkEocykgaW4gdGhlIGRhdGFzZXQiLCBzZXAgPSAiIikpCiAgIyBMaW5lYXJseSBpbnRlcnBvbGF0ZSB0aGUgTkFzCiAgaWYgKG5hX2ludGVycCA9PSBUUlVFKXsKICAgICMgQXNzaWduIHRoZSBwbG90IG1hdHJpeCB0byBhIG5ldyB2YWx1ZQogICAgcGxvdF9tYXRfbmEgPC0gcGxvdF9tYXQKICAgICMgUHJpbnQgYSB3YXJuaW5nCiAgICBwcmludCgiV0FSTklORzogVGhlcmUgd2VyZSBtaXNzaW5nIHZhbHVlcyBpbiB0aGUgcGxvdCBtYXRyaXguIikKICAgICMgSW50ZXJwb2xhdGUgdGhlIE5BJ3MKICAgIGZvciAoaSBpbiAxOm5jb2wocGxvdF9tYXRfbmEpKXsKICAgICAgIyBJbnRlcnBvbGF0ZSB0aGUgZGF0YQogICAgICBwbG90X21hdFssaV0gPC0gbmEuYXBwcm94KHBsb3RfbWF0X25hWyxpXSkKICAgIH0KICB9CiAgIyBtb2RlbCB0eXBlICgxIC0gU0FWLCAyIC0gQVMsIDMgLSBHQVJDSCwgNCAtIEFEQVBUSVZFKQogICMgQWRkIGRlc2NyaXB0aXZlIHRpdGxlcyBvbnRvIHRoZSBwbG90X21hdAogIGNvbG5hbWVzKHBsb3RfbWF0KSA8LSBjKHJlc3BfdmFyLCAiTVYgQ0FWaWFSIiwgIk1WIENBVmlhUiArIEFSIiwgIk1WIENBVmlhUiArIFNBViIsICJNViBDQVZpYVIgKyBBUyIsICJTQVYiLCAiQWJzLiBTbG9wZSIsICJJbmQuIEdBUkNIIiwgIkFkYXB0aXZlIikKICAjIGNvbG5hbWVzKHBsb3RfbWF0KSA8LSBjKCJTUFkiLCAiTVYgQ0FWaWFSIiwgIk1WIENBVmlhUiArIEFSIiwgIk1WIENBVmlhUiArIFNBViIsICJNViBDQVZpYVIgKyBBUyIsICJTQVYiLCAiQWJzLiBTbG9wZSIsICJJbmQuIEdBUkNIIiwgIkFkYXB0aXZlIikKICAjIFBsb3QgZXZlcnl0aGluZwogIHBsb3QgPSBwbHRfZGF0YShwbG90X21hdCwgdGF1ID0gdGF1LCByZXNwX3ZhciA9IHJlc3BfdmFyLCBudGVzdCA9IG50ZXN0KQogICMgQ2FsY3VsYXRlIGxvc3NlcwogIGxfbGlzdCA9IGdlbl9sb3NzX3Rlc3QocGxvdF9tYXQsIHRhdSA9IHRhdSkKICAjIFB1dCBpbnRvIHRhYmxlcwogIHRhYmxlcyA9IHByZXR0eV90YWJsZXMocGxvdF9tYXQsIGxfbGlzdCwgdGF1ID0gdGF1LCBudGVzdCA9IG50ZXN0KQogICMgUnVuIHRoZSBmdW5jdGlvbiBmb3Igb3B0aW1hbCBwIGFuZCBtCiAgcG1fdGFibGUgPSBwcmV0dHlfcG0ob3B0X3ByZWRfbmxbWzNdXSwgb3B0X3ByZWRfYXJ0MVtbNF1dLCBvcHRfcHJlZF9hcnQyW1s0XV0sIG9wdF9wcmVkX2FydDNbWzRdXSkKICAjIEV4cG9ydCB0aGUgbWF0cml4CiAgaWYgKGV4cG9ydF9jc3YgPT0gMSl7CiAgICBleHBfZnVuYyh2YXJfZmlsZSA9IHBsb3RfbWF0LCBwYXRoLCBmaWxlbmFtZSkKICB9CiAgIyBQcmludCB0aGUgdGFibGVzIGFuZCB0aGUgcGxvdAogIHByaW50KHBsb3QpCiAgcHJpbnQodGFibGVzKQogIHByaW50KHBtX3RhYmxlKQogIHJldHVybihsaXN0KHBsb3RfbWF0LCBwbG90LCBsX2xpc3QsIHRhYmxlcywgcGxvdF9tYXRfbmEsIHBtX3RhYmxlKSkKfQpgYGAKCgoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdG8gaW5wdXQgdGhlIFZhUiBmaWxlcywgcGxvdCB0aGVtIGFuZCBnZW5lcmF0ZSB0YWJsZXMKIycKIycgQHBhcmFtIGZpbGVfcGF0aCAtIGZpbGUgcGF0aCB0byB1c2UKIycgQHBhcmFtIGZpbGVuYW1lIC0gbmFtZSBvZiB0aGUgZmlsZQojJyBAcGFyYW0gdGF1IC0gcXVhbnRpbGUgdG8gdXNlCiMnIEBwYXJhbSByZXNwX3ZhciAtIHJlc3BvbnNlIHZhcmlhYmxlIHRvIHVzZSBpbiB0aGUgcGxvdAojJyBAcGFyYW0gbnRlc3QgLSBudW1iZXIgb2YgdGVzdCBwb2ludHMKIycgQHBhcmFtIGNuX2lucHV0IC0gY29sdW1uIG5hbWUgaW5wdXRzCiMnCiMnIEByZXR1cm4gLSBhIGxpc3Qgb2YgdGhlIHh0cyBmaWxlLCB0aGUgcGxvdCwgdGhlIGxvc3MgbGlzdCwgYW5kIHRhYmxlcwojJyBAZXhwb3J0IC0gYSBwbG90IGFuZCB0YWJsZXMKIycKIycgQGV4YW1wbGVzIC0gdGVzdCA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xcGNfMjAwOF91c19ldGYuY3N2IiwgMC4wMSkKdmFyX2lucHV0X2Rpc3AgPSBmdW5jdGlvbihmaWxlX3BhdGgsIGZpbGVuYW1lLCB0YXUsIHJlc3BfdmFyID0gIlNQWSIsIG50ZXN0ID0gMjUwLCBjbl9pbnB1dCA9IGMoIlNQWSIsICJNViBDQVZpYVIiLCAiTVYgQ0FWaWFSICsgQVIiLCAiTVYgQ0FWaWFSICsgU0FWIiwgIk1WIENBVmlhUiArIEFTIiwgIlNBViIsICJBYnMuIFNsb3BlIiwgIkluZC4gR0FSQ0giLCAiQWRhcHRpdmUiKSl7CiMgdmFyX2lucHV0X2Rpc3AgPSBmdW5jdGlvbihmaWxlX3BhdGgsIGZpbGVuYW1lLCB0YXUsIHJlc3BfdmFyID0gIlNQWSIsIG50ZXN0ID0gMjUwLCBjbl9pbnB1dCA9IGMoIlNQWSIsICJNViBDQVZpYVIiLCAiTVYgQ0FWaWFSICsgQVIiLCAiTVYgQ0FWaWFSICsgU0FWIiwgIk1WIENBVmlhUiArIEFTIiwgIlNBViIsICJBYnMuIFNsb3BlIiwgIkluZC4gR0FSQ0giLCAiQWRhcHRpdmUiKSl7CiAgIyBJbXBvcnQgZGF0YQogIHBsb3RfbWF0ID0gcmVhZC5jc3YocGFzdGUwKGZpbGVfcGF0aCxmaWxlbmFtZSksIHNlcCA9ICIsIiwgaGVhZGVyID0gVCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQogICMgRml4IGRhdGUgZm9ybWF0CiAgcGxvdF9tYXQkSW5kZXggPSBhcy5EYXRlKHBsb3RfbWF0JEluZGV4KQogICMgQ29udmVydCB0byBhbiB4dHMKICBwbG90X21hdCA9IHh0cyhwbG90X21hdFssLTFdLCBvcmRlci5ieSA9IHBsb3RfbWF0WywxXSkKICAjIEZpeCBjb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhwbG90X21hdCkgPC0gY25faW5wdXQKICAjIFBsb3QgZXZlcnl0aGluZwogIHBsdF9kYXRhKHBsb3RfbWF0LCB0YXUgPSB0YXUsIHJlc3BfdmFyID0gcmVzcF92YXIsIG50ZXN0ID0gbnRlc3QpCiAgIyBwbG90ID0gcGx0X2RhdGEocGxvdF9tYXQsIHRhdSA9IHRhdSwgcmVzcF92YXIgPSByZXNwX3ZhciwgbnRlc3QgPSBudGVzdCkKICAjIENhbGN1bGF0ZSBsb3NzZXMKICBsX2xpc3QgPSBnZW5fbG9zc190ZXN0KHBsb3RfbWF0LCB0YXUgPSB0YXUpCiAgIyBQdXQgaW50byB0YWJsZXMKICBkZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQobF9saXN0W1sxXV0sIGxfbGlzdFtbMl1dKSkKICAjIENhbGN1bGF0ZSBpbml0YWwgYW5kIGVuZGluZyB0aW1lIHZhbHVlCiAgc3RhcnQgPSBpbmRleChwbG90X21hdClbMV0KICBlbmQgPSBpbmRleChwbG90X21hdClbbnJvdyhwbG90X21hdCldCiAgIyBBZGQgcm93L2NvbHVtbiBuYW1lcwogIGNvbG5hbWVzKGRmKSA8LSBjb2xuYW1lcyhwbG90X21hdFssLTFdKQogIHJvd25hbWVzKGRmKSA8LSBjKCJMb3NzZXMiLCAiVmFSIEJyZWFrcyAoJSkiKQogICMgQ29udmVydCB0byBhIHRhYmxlCiAgcHJpbnQoZGYsIGRpZ2l0cyA9IDMpCiAgIyBwcmludChmb3JtYXR0YWJsZShkZiwgZGlnaXRzID0gMykpCiAgIyBkZiAlPiUga2FibGUoY2FwdGlvbiA9IHBhc3RlKCJDb21wYXJpc29uIG9mIFZhUiBNZXRob2RzIGZvciBhICIsIHRhdSoxMDAsICIlIFZhUiIsIHNlcCA9ICIiKSwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9IHBhc3RlKCJDYWxjdWxhdGVkIHVzaW5nIiwgbnRlc3QsICJ0cmFkaW5nIGRheXMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKQogICMgcG1fdGFibGUgPSBwcmV0dHlfdGFibGVzKHBsb3RfbWF0LCBsX2xpc3QsIHRhdSA9IHRhdSwgbnRlc3QgPSBudGVzdCkKICAjIFByaW50IHRoZSB0YWJsZXMgYW5kIHRoZSBwbG90CiAgIyBwcmludChwbG90KQogICMgcHJpbnQodGFibGVzKQogICMgcHJpbnQocG1fdGFibGUpCiAgIyBSZXR1cm4gdGhlIHh0cywgdGhlIHBsb3QsIHRoZSBsb3NzIGxpc3QsIGFuZCB0aGUgdGFibGVzCiAgcmV0dXJuKGxpc3QocGxvdF9tYXQpKQogICMgcmV0dXJuKGxpc3QocGxvdF9tYXQsIHBsb3QsIGxfbGlzdCwgdGFibGVzKSkKfQpgYGAKCgojIyAyMDA4IEVuZGluZwoKIyMjIFUuUy4gRVRGcwoKYGBge3J9CiMgcmV0dXJuKGxpc3QocGxvdF9tYXQsIHBsb3QsIGxfbGlzdCwgdGFibGVzKSkKCiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAwOF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xcGNfMjAwOF91c19ldGYuY3N2IiwgMC4wMSkKIyBwcmV0dHlfdGFibGVzKHYxXzIwMDhfdXNldGZbWzFdXSwgdjFfMjAwOF91c2V0ZltbM11dLCB0YXUgPSAwLjAxLCBudGVzdCA9IDI1MCkKdjVfMjAwOF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl81cGNfMjAwOF91c19ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMDhfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDA4X3VzX2V0Zi5jc3YiLCAwLjEwKQoKIyBoZWFkKHYxMF8yMDA4X3VzZXRmW1sxXV0pCiMgdjEwXzIwMDhfdXNldGYKYGBgCgpUaGUgcmVzdWx0cyBmb3IgdGhlIFUuUy4gRVRGcyBjbGVhcmx5IHNob3cgdGhhdCB0aGUgdW5pdmFyaWF0ZSBtb2RlbCBvdXRwZXJmb3JtcyB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGR1cmluZyB0aGUgZ3JlYXQgcmVjZXNzaW9uLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAwOCAtIDFzdCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAwOF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAwOF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMDhfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAwOF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDA4X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDA4X3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAwOF91c2V0ZltbMV1dKQpgYGAKCiMjIyBHbG9iYWwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAwOF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfZ2xvYl9ldGYuY3N2IiwgMC4wMSkKdjVfMjAwOF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMDhfZ2xvYl9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMDhfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAwOF9nbG9iX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCldoaWxlIHRoZSBtb2RlbCB3aXRoIHRoZSBnbG9iYWwgRVRGcyBhcyBwcmVkaWN0b3JzIHBlcmZvcm1zIGJldHRlciB0aGFuIHRoZSBtb2RlbCB3aXRoIFUuUy4gRVRGcywgdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsIG91dHBlcmZvcm1zIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDA4IC0gMm5kIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDA4X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDA4X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDA4X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMDhfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDA4X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDA4X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDA4X3VzZXRmW1sxXV0pCmBgYAoKIyMjIENvbW1vZGl0eSBFVEZzCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDA4IC0gM3JkIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDA4X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMDhfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMDhfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDA4X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAwOF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDA4X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDA4X3VzZXRmW1sxXV0pCmBgYAoKCgojIyMgQm9uZCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDA4X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl8xcGNfMjAwOF9ib25kX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDA4X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl81cGNfMjAwOF9ib25kX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAwOF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDA4X2JvbmRfZXRmLmNzdiIsIDAuMTApCmBgYAoKQXMgd2l0aCB0aGUgcHJldmlvdXMgdHdvIHJ1bnMsIHRoZSB1bml2YXJpYXRlIG1vZGVsIG91dHBlcmZvcm1zIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwuCgpgYGB7cn0KIyBpU2hhcmVzIDEtMyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoU0hZKQojIGlTaGFyZXMgNy0xMCBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoSUVGKQojIGlTaGFyZXMgMjArIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChUTFQpCiMgaVNoYXJlcyBpQm94eCAkIEludmVzdG1lbnQgR3JhZGUgQ29ycG9yYXRlIEJvbmQgRVRGIChMUUQpCgojIDElLCA1JSwgMTAlIFZhUiAtIDIwMDggLSA0dGggc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMDhfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAwOF9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDA4X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAwOF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMDhfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDA4X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMDhfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMDhfdXNldGZbWzFdXSkKYGBgCgojIyMgQWxsIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMDhfYWxsZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsInZhcl8xcGNfMjAwOF9hbGxfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMDhfYWxsZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsInZhcl81cGNfMjAwOF9hbGxfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDA4X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDA4X2FsbF9ldGYuY3N2IiwgMC4xMCkKYGBgCgpXaGlsZSB0aGUgaW5jbHVzaW9uIG9mIG1vcmUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIHNlZW1zIHRvIGhlbHAgdGhlIGZvcmVjYXN0LCB0aGUgdW5pdmFyaWF0ZSBtb2RlbCBvdXRwZXJmb3JtcyB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAwOCAtIDV0aCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAwOF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDA4X2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMDhfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDA4X2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDA4X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMDhfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAwOF91c2V0ZltbMV1dKQpgYGAKCiMjIDIwMTAgRW5kaW5nCgojIyMgVS5TLiBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDEwX3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzFwY18yMDEwX3VzX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDEwX3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzVwY18yMDEwX3VzX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxMF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTBfdXNfZXRmLmNzdiIsIDAuMTApCmBgYAoKVGhlIHJlc3VsdHMgYXJlIG11Y2ggYmV0dGVyIGZvciB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGhlcmUgZHVyaW5nIGEgbW9yZSBiZW5pZ24gcGVyaW9kLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxMCAtIDFzdCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxMF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxMF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTBfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxMF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDEwX3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDEwX3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxMF91c2V0ZltbMV1dKQpgYGAKCiMjIyBHbG9iYWwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxMF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxMF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTBfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxMF9nbG9iX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkFzIHdpdGggdGhlIFUuUy4gRVRGcywgdGhlIHJlc3VsdHMgYXJlIGJldHRlci4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTAgLSAybmQgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTBfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTBfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxMF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDEwX3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTBfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTBfdXNldGZbWzFdXSkKYGBgCgojIyMgQ29tbW9kaXR5IEVURnMKCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTAgLSAzcmQgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTBfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxMF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDEwX3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxMF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTBfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDEwX2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMTBfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTBfdXNldGZbWzFdXSkKYGBgCgojIyMgQm9uZCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDEwX2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl8xcGNfMjAxMF9ib25kX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDEwX2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl81cGNfMjAxMF9ib25kX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxMF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDEwX2JvbmRfZXRmLmNzdiIsIDAuMTApCmBgYAoKQXMgd2l0aCB0aGUgcHJldmlvdXMgdHdvIHJ1bnMsIHRoZSByZXN1bHRzIGZyb20gdGhlIGJvbmQgRVRGcyBhcmUgYmV0dGVyIHRoYW4gdGhvc2UgZnJvbSAyMDA4LgoKYGBge3J9CiMgaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKIyBpU2hhcmVzIDctMTAgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKElFRikKIyBpU2hhcmVzIDIwKyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoVExUKQojIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDEwIC0gNHRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDEwX2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTBfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTBfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDEwX2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxMF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDEwX2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDEwX3VzZXRmW1sxXV0pCmBgYAoKIyMjIEFsbCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDEwX2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTBfYWxsX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDEwX2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTBfYWxsX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxMF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxMF9hbGxfZXRmLmNzdiIsIDAuMTApCmBgYAoKVGhlIGluY2x1c2lvbiBvZiBhbGwgcHJlZGljdG9ycyByZXZlYWxzIHNpbWlsYXIgcmVzdWx0cyBmb3IgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbHMgYXMgdGhlIHByZXZpb3VzIGZvcmVjYXN0czsgdGhlIHJlc3VsdHMgYXJlIGdlbmVyYWxseSBpbi1saW5lIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbC4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTAgLSA1dGggc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTBfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxMF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDEwX2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxMF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxMF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDEwX2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTBfdXNldGZbWzFdXSkKYGBgCgojIyAyMDE0IEVuZGluZwoKIyMjIFUuUy4gRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xcGNfMjAxNF91c19ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl81cGNfMjAxNF91c19ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTRfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDE0X3VzX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkFzIHdpdGggdGhlIHJlc3VsdHMgaW4gMjAxNCwgdGhlIHJlc3VsdHMgZnJvbSB0aGUgVS5TLiBFVEZzIHNob3dzIGEgc2ltaWxhciBxdWFsaXR5IG9mIHByZWRpY3Rpb25zLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNCAtIDFzdCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTRfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxNF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDE0X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE0X3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNF91c2V0ZltbMV1dKQpgYGAKCiMjIyBHbG9iYWwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTRfZ2xvYl9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNF9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTRfZ2xvYl9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTRfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNF9nbG9iX2V0Zi5jc3YiLCAwLjEwKQpgYGAKClRoZSByZXN1bHRzIHNob3cgdGhhdCB0aGUgbXVsdGl2YXJpYXRlIHByZWRpY3Rpb25zIGFyZSBvZiBzaW1pbGFyIHF1YWxpdHkgdG8gdGhlIHByZWRpY3Rpb25zIGZyb20gdGhlIHVuaXZhcmlhdGUgbW9kZWwuIAoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNCAtIDJuZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE0X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNF91c2V0ZltbMV1dKQpgYGAKCiMjIyBDb21tb2RpdHkgRVRGcwoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNCAtIDNyZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE0X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE0X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTRfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNF91c2V0ZltbMV1dKQpgYGAKCiMjIyBCb25kIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTRfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE0X2JvbmRfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTRfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE0X2JvbmRfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDE0X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTRfYm9uZF9ldGYuY3N2IiwgMC4xMCkKYGBgCgpBcyB3aXRoIHRoZSBvdGhlciB0d28gc2V0cyBvZiByZWdyZXNzb3JzLCB0aGUgcmVzdWx0cyBoZXJlIHNob3cgdGhhdCB0aGUgbXVsdGl2YXJpYXRlIHByZWRpY3Rpb25zIGFyZSBvZiBzaW1pbGFyIHF1YWxpdHkgdG8gdGhlIHByZWRpY3Rpb25zIGZyb20gdGhlIHVuaXZhcmlhdGUgbW9kZWwuIAoKYGBge3J9CiMgaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKIyBpU2hhcmVzIDctMTAgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKElFRikKIyBpU2hhcmVzIDIwKyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoVExUKQojIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE0IC0gNHRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE0X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTRfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTRfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE0X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE0X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE0X3VzZXRmW1sxXV0pCmBgYAoKIyMjIEFsbCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDE0X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTRfYWxsX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDE0X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTRfYWxsX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxNF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNF9hbGxfZXRmLmNzdiIsIDAuMTApCmBgYAoKSW5jbHVkaW5nIGFsbCB0aGUgRVRGcyBhcyByZWdyZXNzb3JzIHByb3ZpZGVzIGEgbXVsdGl2YXJpYXRlIGZvcmVjYXN0IHdpdGggc2ltaWxhciBhY2N1cmFjeSB0byB0aGF0IG9mIHRoZSB1bml2YXJpYXRlIG1vZGVsLiAKCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTQgLSA1dGggc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTRfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE0X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE0X2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTRfdXNldGZbWzFdXSkKYGBgCgoKIyMgMjAxNiBFbmRpbmcKCiMjIyBVLlMuIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTZfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTZfdXNfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTZfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTZfdXNfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDE2X3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNl91c19ldGYuY3N2IiwgMC4xMCkKYGBgCgpBcyB3aXRoIHRoZSBmb3JlY2FzdCBpbiAyMDEwIGFuZCAyMDE0LCBpbmNsdWRpbmcgdGhlIFUuUy4gRVRGcyBhcyBwcmVkaWN0b3JzIGluIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwgZ2l2ZXMgc2ltaWxhciByZXN1bHRzIHRvIHRoYXQgb2YgdGhlIHVuaXZhcmlhdGUgbW9kZWwuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE2IC0gMXN0IHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE2X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE2X3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNl91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE2X3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTZfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMTZfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE2X3VzZXRmW1sxXV0pCmBgYAoKIyMjIEdsb2JhbCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDE2X2dsb2JldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsInZhcl8xcGNfMjAxNl9nbG9iX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDE2X2dsb2JldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsInZhcl81cGNfMjAxNl9nbG9iX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxNl9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDE2X2dsb2JfZXRmLmNzdiIsIDAuMTApCmBgYAoKVGhlIGdsb2JhbCBFVEZzIGFzIHByZWRpY3RvcnMgcHJvdmlkZSBzb2xpZCByZXN1bHRzIGFzIHdlbGwuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE2IC0gMm5kIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE2X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE2X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE2X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTZfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxNl91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDE2X2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE2X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE2X3VzZXRmW1sxXV0pCmBgYAoKIyMjIENvbW1vZGl0eSBFVEZzCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE2IC0gM3JkIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE2X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTZfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNl91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTZfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE2X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNl9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE2X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE2X3VzZXRmW1sxXV0pCmBgYAoKIyMjIEJvbmQgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNl9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTZfYm9uZF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNl9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTZfYm9uZF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTZfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNl9ib25kX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkFzIHdpdGggdGhlIFUuUy4gYW5kIEdsb2JhbCBFVEZzLCB0aGUgYm9uZCBFVEZzIHByb3ZpZGUgZ29vZCByZXN1bHRzLgoKYGBge3J9CiMgaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKIyBpU2hhcmVzIDctMTAgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKElFRikKIyBpU2hhcmVzIDIwKyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoVExUKQojIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE2IC0gNHRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE2X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTZfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNl91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTZfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE2X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNl9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE2X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE2X3VzZXRmW1sxXV0pCmBgYAoKIyMjIEFsbCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDE2X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTZfYWxsX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDE2X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTZfYWxsX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxNl9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNl9hbGxfZXRmLmNzdiIsIDAuMTApCmBgYAoKSW5jbHVkaW5nIGFsbCBFVEZzIGFzIHByZWRpY3RvcnMgeWllbGRzIGdvb2QgcXVhbGl0eSByZXN1bHRzIGZvciB0aGUgMjAxNiB0ZXN0IHBlcmlvZC4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTYgLSA1dGggc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTZfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNl9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE2X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNl9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNl9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE2X2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTZfdXNldGZbWzFdXSkKYGBgCgojIENvbmNsdXNpb25zIGFuZCBGdXR1cmUgV29yawoKVGhlIHByb2JsZW0gb2YgaG93IHRvIHByZWRpY3QgYSBsb3cgcXVhbnRpbGUgb2YgYSBzdG9jaydzIGxvZyByZXR1cm4gd2hlbiB0aGUgdHJhaW5pbmcgc2FtcGxlIGlzIHN1YnN0YW50aWFsbHkgZGlmZmVyZW50IGZyb20gdGhlIHRlc3Qgc2NlbmFyaW8gaXMgYW4gZW5vcm1vdXNseSBkaWZmaWN1bHQgcHJvYmxlbS4gQWxtb3N0IGF4aW9tYXRpY2FsbHksIHRoZSBkaXN0cmlidXRpb24gaXMgbm9uc3RhdGlvbmFyeSBvdmVyIHRpbWUuIEhvdyBpcyBpdCBwb3NzaWJsZSB0byBwcmVkaWN0IHRoZSByZXR1cm4gb2YgYW4gaW5kZXggbGlrZSB0aGUgUyZQNTAwIGR1cmluZyBhIHBlcmlvZCBvZiBtYXJrZXQgdHVybW9pbCBzdWNoIGFzIHRoZSBHcmVhdCBSZWNlc3Npb24/IFdoaWxlIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbCBwZXJmb3JtcyBjb21wYXJhdGl2ZWx5IHdlbGwgZHVyaW5nIHRpbWVzIG9mIHN0cmVzcywgaXQgcGVyZm9ybXMgYWJvdXQgdGhlIHNhbWUgYXMgdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwgZHVyaW5nIG1vcmUgYmVuaWduIGVjb25vbWljIHBlcmlvZHMuCgpUaGlzIGNvbmNsdXNpb24gZHJhd24gZnJvbSB0aGUgYWJvdmUgcmVzdWx0cyBtaWdodCBzdXBwb3J0IHRoZSBub3Rpb24gb2YgY29tYmluaW5nIHRoZSB0d28gbW9kZWxzIGluIHNvbWUgc29ydCBvZiBhIG1peHR1cmUgbW9kZWwgLSBhaW1pbmcgdG8gdXNlIHRoZSBiYXNrZXQgb2YgRVRGcyBkdXJpbmcgZ29vZCB0aW1lcywgYW5kIHVzZSB0aGUgQ0FWaWFSIEFSTUEgc3BlY2lmaWNhdGlvbiBkdXJpbmcgYmFkIHRpbWVzLiBUaGUgYXBwcm9hY2ggb2YgdXNpbmcgRVRGcyBhbGxvd3MgYSBwcmVkaWN0aW9uIGJhc2VkIG9uIGZvcndhcmQtbG9va2luZyBleHBlY3RhdGlvbnMgb2YgZnVuZGFtZW50YWwgZmFjdG9ycy4gSW5kZWVkLCBFVEZzIGFyZSBqdXN0IGJhc2tldHMgb2YgaW5kaXZpZHVhbCBzdG9ja3Mgb3IgYm9uZHMsIGFuZCB0aG9zZSBzZWN1cml0aWVzIGFyZSAoaW4gdGhlb3J5KSBiYXNlZCBvbiByYXRpb25hbCBleHBlY3RhdGlvbnMgYWJvdXQgZnV0dXJlIHJlc291cmNlcywgbWFya2V0IGNvbmRpdGlvbnMsIGV0YyAtIHRoZSBtaWNyb2ZvdW5kYXRpb25zIG9mIHdoYXQgZHJpdmVzIG91ciBlY29ub215LiBUaGUgQVJNQSBzcGVjaWZpY2F0aW9uLCB3aGlsZSBwcmFjdGljYWxseSBhbmQgc3RhdGlzdGljYWxseSBzb3VuZCwgaXMgY29udHJhZGljdGVkIGJ5IGVjb25vbWljIHRoZW9yeSBhbmQgcHJhY3RpY2UgLSB0aGUgd2VhayBmb3JtIG9mIHRoZSBlZmZpY2llbnQgbWFya2V0IGh5cG90aGVzaXMgc3RhdGVzIHRoYXQgaXQgaXMgaW1wb3NzaWJsZSB0byBmb3JlY2FzdCBmdXR1cmUgdmFsdWVzIG9mIGFzc2V0IHByaWNlcyB1c2luZyBwYXN0IHZhbHVlcy4gQnV0IHBlcmhhcHMgdGhpcyB2aWV3IGlzIGluY29tcGxldGUuCgpBbnkgbW9kZWwgdGhhdCBhdHRlbXB0cyB0byBjYXB0dXJlIHJlbGF0aW9uc2hpcHMgaW4gdGhlIHJlYWwgd29ybGQgd2lsbCBvbmx5IHdvcmsgdW50aWwgYW4gb21pdHRlZCB2YXJpYWJsZSBpcyBmb3VuZC4gVGhlIGVsZWdhbmNlIG9mIHRoZSBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVsIGlzIHRoYXQgaXQgcHJvdmlkZXMgaW5zaWdodCBpbnRvIHdoeSBhIHByZWRpY3Rpb24gaXMgd3Jvbmc7IHRoZSBjaGFuZ2UgaW4gdGhlIGFuZ2xlIGJldHdlZW4gcmVzdWx0YW50IHZlY3RvcnMgaXMgYSBzZW5zaWJsZSBtZWFzdXJlbWVudCBvZiBlY29ub21pYyBjaGFuZ2Vwb2ludHMgKENIQU5HRSkuIEhvd2V2ZXIsIGVycm9ycyBpbiB0aGUgd29ybGQgYXJlIGNvc3RseSwgYW5kIGl0J3Mgd2lzaGZ1bCB0aGlua2luZyB0byBzYXkgdGhhdCBleHBsYWluaW5nIHdoeSB0aGUgZXJyb3Igb2NjdXJyZWQgaXMgc3VmZmljaWVudC4KCkFzIHN1Y2gsIGZvciBmdXR1cmUgd29yayBpdCdzIHdvcnRoIGV4cGxvcmluZyB0aGUgbm90aW9uIG9mIHdlaWdodGluZyBhbiBBUk1BLWFwcHJvYWNoIG1vcmUgaGVhdmlseSB3aGVuIHByZWRpY3Rpb25zIHVzaW5nIGZ1bmRhbWVudGFscyB3ZXJlIHRvbyBoaWdoLCB0aGVuIG5vdCBvbmx5IHdvdWxkIHRoaXMgYWZ0ZXItdGhlLWZhY3QgcmVjb2duaXRpb24gYmUgYWNoaWV2ZWQsIGJ1dCBhbHNvIGEgaGllcmFyY2hpY2FsIG1vZGVsIHRoYXQgY2FwdHVyZXMgZnVuZGFtZW50YWwgcmVsYXRpb25zaGlwcyBpbiB0aGUgZWNvbm9teSBhbmQgcG90ZW50aWFsbHkgY2hhbmdlcyBvdXIgdW5kZXJzdGFuZGluZyBvZiBhc3NldCBwcmljZXMgaW4gZ2VuZXJhbCAtIGEgc3ludGhlc2lzIGJldHdlZW4gS2V5bmVzJyBhbmltYWwgc3Bpcml0cyBkdXJpbmcgYSB0aW1lIG9mIHNldmVyZSBjcmlzaXM7IHdoZXJlIGEgbW9kZWwgY2Fubm90IGV4cGxhaW4gc2hpZnRzLCBhbmQgYSBtb3JlIHJhdGlvbmFsIHdvcmxkIHRoYXQgZXhwbGFpbnMgb3RoZXIgcGVyaW9kcy4gSW4gYWRkaXRpb24gdG8gc2lnbmlmaWNhbnQgcHJlZGljdGl2ZSBwb3dlciBiZWNhdXNlIG9mIHRoZSBzd2l0Y2hpbmcgYmV0d2VlbiB0aGUgdHdvIHdvcmxkcywgdGhlcmUncyBhbHNvIGFuIGVsZWdhbnQgZXhwbGFuYXRpb247IGEgd2F5IHRvIGV4cGxhaW4gY2hhbmdlcyBpbiB0aGUgdXNlZnVsbmVzcyBvZiB0aGUgdW5kZXJwaW5uaW5ncyBpbiB0aGUgZWNvbm9teS4gQmVjYXVzZSBvZiB0aGUgZmxleGliaWxpdHkgb2YgdGhlIG1vZGVsLCBpdCdzIGVudGlyZWx5IHBvc3NpYmxlIHRoYXQgYSB3aG9sZSBnYW11dCBvZiB2YXJpYWJsZXMgY291bGQgYmUgdG9zc2VkIGluIGFuZCBiYWNrdGVzdGVkIHRvIHdoZW4gImNoYW5nZXBvaW50cyIgb2NjdXJyZWQuIAoKQWRkaXRpb25hbCBmdXR1cmUgd29yayBpbnZvbHZlcyBkZXZlbG9waW5nIHRoZW9yZXRpY2FsIGd1YXJhbnRlZXMgb24gdGhlIHBhcmFtZXRlcnMgaW4gdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwuIE9uZSBhZHZhbnRhZ2Ugb2YgYm90aCB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsIGFuZCB0aGUgQ0FWaWFSIG1vZGVsIGlzIHRoYXQgYm90aCBoYXZlIHRoZW9yZW1zIGFib3V0IGFzeW1wdG90aWMgbm9ybWFsaXR5IGFuZCBjb25zaXN0ZW5jeSBbQ09ORklSTV0uCgoKIyBDb2RlIEFwcGVuZGl4CgpgYGB7ciByZWYubGFiZWw9a25pdHI6OmFsbF9sYWJlbHMoKSwgZWNobyA9IFQsIGV2YWwgPSBGfQpgYGAKCiMgTGl0ZXJhdHVyZSBDaXRlZAo=